Alla ricerca di Poly Nemo!


11

Oh no! Nemo, il nostro piccolo pesce pagliaccio si perde in questo oceano ASCII e suo padre Marlin sta cercando di trovarlo.

Il tuo compito è di portare Marlin in sicurezza su Nemo. Ma attenzione, abbiamo una frenesia di cibo Bruce a piede libero, quindi meglio evitarlo a tutti i costi!

Dettagli

Ti viene data una griglia oceanica ASCII rettangolare contenente solo alfabeti minuscoli a-z. Questo oceano avrà nemo, marline bruceal suo interno, sotto forma di un poliomino continuo, partendo sempre dalla parte più alta della prima colonna del poliomino. Ad esempio, tra tutti i possibili tetrominos, quelli validi sono elencati nello snippet di seguito

Ma moduli come questi non sono validi e non saranno presenti nell'input:

omen

ne
mo

nem
o

o
m
en

nem
 o

n
eo
m

Infine, il tuo compito è quello di trovare un percorso dalla marlintessera poliomino alla tessera nemopoliomino assicurandoti che qualsiasi cella nel tuo percorso non sia adiacente alla brucetessera poliomino. L'output dovrebbe sostituire tutti gli alfabeti che non fanno parte del marlinriquadro, del nemoriquadro e del percorso che li collega entrambi con un carattere dell'intervallo ASCII stampabile (incluso lo spazio) diverso da quello minuscolo a-z.

Esempio

Se l'oceano di input è il seguente:

oxknvvolacycxg
xmliuzsxpdzkpw
warukpyhcldlgu
tucpzymenmoyhk
qnvtbsalyfrlyn
cicjrucejhiaeb
bzqfnfwqtrzqbp
ywvjanjdtzcoyh
xsjeyemojwtyhi
mcefvugvqabqtt
oihfadeihvzakk
pjuicqduvnwscv

(con i 3 polominomi:

...n..........
.mli..........
.ar...........
..............
....b.........
....ruce......
..............
.....n........
.....emo......
..............
..............
..............

)

Quindi una soluzione valida potrebbe apparire come:

...n..........
.mli..........
.ar...........
.u............
.n............
.i............
.z............
.wvjan........
.....emo......
..............
..............
..............

Lo snippet di seguito contiene alcuni altri esempi:

Appunti

  • La griglia sarà sempre un rettangolo perfetto e conterrà solo una tessera di poliomino di nemo, marline bruce.
  • Il tuo percorso non deve attraversare brucené una delle 4 celle adiacenti (su, giù, sinistra e destra) di nessuna cella nella brucetessera.
  • È sempre garantito che ci sarà almeno un percorso valido da marlina nemo.
  • Non è necessario un percorso più breve qui, quindi impazzisci!
  • Anche se non è necessario trovare il percorso più breve, qualsiasi cella nel percorso (percorso escluso Marlin o nemo) non può essere adiacente a più di altre due celle nel percorso.
  • Il percorso non dovrebbe attraversare le tessere marlino nemo, poiché confonderebbe i pesciolini nella scelta di una direzione.
  • Come al solito, è possibile scrivere un programma o una funzione, prendendo input tramite STDIN (o equivalente più vicino), argomento della riga di comando o parametro di funzione e producendo output tramite STDOUT (o equivalente più vicino), valore di ritorno o parametro di funzione (out).
  • Se non è possibile immettere più righe, è possibile supporre che la griglia sia unita dal |carattere anziché \n. Puoi anche prendere l'input come una matrice di righe della griglia.

Questo è il golf del codice, quindi vince la voce più breve in byte.


Il percorso può passare attraverso Marlin (o nemo)? la soluzione di cui sopra sarebbe ancora valida se fosse visibile il kprecedente lin marlin? (facendo il percorso da n in marlin a nemo)
KSab

@KSab Direi di no perché confonderebbe Marlin :)
Ottimizzatore

Risposte:


4

Matlab 560

560 byte durante la rimozione di tutti gli spazi non necessari, tutti i punti e virgola e tutti i commenti. Potrei giocare a golf molto di più, ma ora sono stanco (forse domani ...) Buona notte a tutti.

PS: ho ipotizzato che il percorso deve avere una connessione di 4 vicinato ('+').

function c(A)
Z = [0,1,0;1,1,1;0,1,0];
Br = q('bruce');
Bn = conv2(Br,ones(3),'s')>0;
Ne = q('nemo');
Ma = q('marlin');
%construct path marlin to nemo
U=Ma>0;M=A*Inf;
M(U)=0;
for k=1:2*sum(size(A))%upper bound for path length
    %expand
    V=imdilate(U,Z);
    V(Bn)=0;
    M(V-U==1)=k;
    U=V;
    %disp(M)
end
%go back from nemo to marlin
Pr=reshape(1:numel(A),size(A));
[i,j]=find(Ne);
m=M(i(1),j(1));%value
P=A*0;%path image
P(i(1),j(1))=1;
for k=m:-1:1
    %find neighbour of (i(1),j(1)) with value m-1
    U=imdilate(P,Z);
    F = M==k;
    G = F&U;
    mask = Pr == min(Pr(F & U));
    P(mask)=1; 
end
A(~P & ~Ma & ~Ne)='.';
disp(A)



    function M = q(s)%find string in matrix, A ascii, M mask
        M = A*0;
        m=numel(s);
        N = M+1;%all neighbours
        for k=1:m;
            M(A==s(k) & N)=k;%only set the ones that were in the neighbourhood of last
            L=M==k;
            N=imdilate(L,Z);
        end
        for k=m:-1:2
            %set all that are not neighbour to next higher highest to zero
            L=M==k;
            N=imdilate(L,Z);
            M(M==k-1 & ~N)=0;
        end
    end


end

Funzione di chiamata: (newline non necessario)

c(['oxknvvolacycxg',
'xmliuzsxpdzkpw',
'warukpyhcldlgu',
'tucpzymenmoyhk',
'qnvtbsalyfrlyn',
'cicjrucejhiaeb',
'bzqfnfwqtrzqbp',
'ywvjanjdtzcoyh',
'xsjeyemojwtyhi',
'mcefvugvqabqtt',
'oihfadeihvzakk',
'pjuicqduvnwscv']);

Produzione:

...n..........
.mli..........
.ar...........
..c...........
..v...........
..c...........
..q...........
..vjan........
.....emo......
..............
..............
..............

Come funziona

Estrazione di nomi

La prima parte sta estraendo i nomi nemo, ad esempio , che è fatto dalla funzione q(). La funzione prima contrassegna tutto come 0, quindi le occorrenze prima lettera del nome come 1, quindi seconda lettera come 2se ci fosse un 1vicino, poi la terza e così via. Dopo ciò dovrebbe esserci nel caso di nemouno solo 4. Da ciò andiamo indietro fino a quando non abbiamo trovato il 1nuovo e quindi cancelliamo tutti gli altri numeri che erano maggiori, quindi otteniamo una bella maschera in cui le lettere nemosono mascherate. Lo facciamo per tutti e tre i nomi e possiamo quindi procedere alla ricerca di un percorso.

Trovare il percorso

Iniziamo dalle posizioni di Marlins e inviamo un'onda d'urto attraverso il buco 'immagine' passo dopo passo. In ogni passaggio aumentiamo il contatore della distanza e contrassegniamo i "pixel" sotto il fronte d'onda con la distanza corrente. (Come di solito viene fatto con gli algoritmi del percorso più breve.) Questo fronte d'onda viene ovviamente bloccato dall'area di Bruce, quindi scorrerà intorno a lui. Questo passaggio viene ripetuto fino al raggiungimento di un limite superiore. Questo limite superiore (certamente molto allentato) è ora la circonferenza dell '"immagine" (i percorsi più corti saranno comunque molto più corti). Nel caso di test sembra qualcosa del genere:

 2 1 1  0  1  2  3  4  5  6  7  8  9 10
 1 0 0  0  1  2  3  4  5  6  7  8  9 10
 1 0 0  1  2  3  4  5  6  7  8  9 10 11
 2 1 1  _  _  _  5  6  7  8  9 10 11 12
 3 2 2  _  _  _  _  _  _  9 10 11 12 13
 4 3 3  _  _  _  _  _  _ 10 11 12 13 14
 5 4 4  _  _  _  _  _  _ 11 12 13 14 15
 6 5 5  6  7  8  9 10 11 12 13 14 15 16
 7 6 6  7  8  9 10 11 12 13 14 15 16 17
 8 7 7  8  9 10 11 12 13 14 15 16 17 18
 9 8 8  9 10 11 12 13 14 15 16 17 18 19
10 9 9 10 11 12 13 14 15 16 17 18 19 20

Ora inizia con i nemopixel e diminuisci il contatore della distanza in ogni passaggio e aggiungi un vicino con la distanza inferiore successiva (secondo quella mappa di distanza che abbiamo calcolato in precedenza) al nostro percorso.


3

Python 2 - 658

Molto inefficiente sia nel tempo che nella memoria. La funzione per identificare i modelli è la funzione ricorsiva S, e la funzione per trovare i percorsi è la C, che è fondamentalmente un'implementazione A * orribilmente inefficiente.

G=input().split('\n')
R=range
S=lambda g,x,y,s,B:[[(x,y)]+r for a,b in[(-1,0),(0,-1),(0,1),(1,0)]for r in S(g,x+a,y+b,s[1:],B)if B(x,y)and s[0]==g[y][x]]if s else[[]]
C=lambda l,N,B:[i for i in l if i[-1]in N]or C([i+[(i[-1][0]+c,i[-1][1]+d)]for i in l for c,d in [(-1,0),(0,-1),(0,1),(1,0)]if all(1<abs(i[-1][0]+c-a)or 1<abs(i[-1][1]+d-b)for a,b in B)],N,B)
X,Y=len(G[0]),len(G)
N,M,B=[filter(list,[S(G,s,t,e,lambda a,b:0<=a<X and 0<=b<Y and Y*(a-s)+b-t>=0)for s in R(X)for t in R(Y)])[0][0]for e in["nemo","marlin","bruce"]]
print'\n'.join(''.join(G[y][x]if(x,y)in N+M+min([C([[k]],N,B)[0]for k in M],key=lambda i:len(i))else'.'for x in R(X))for y in R(Y))

Per i test usa questo (leggermente) meno golfizzato (che calcola il percorso una volta invece per ogni tessera)

G=input().split('\n')
R=range
S=lambda g,x,y,s,B:[[(x,y)]+r for a,b in[(-1,0),(0,-1),(0,1),(1,0)]for r in S(g,x+a,y+b,s[1:],B)if B(x,y)and s[0]==g[y][x]]if s else[[]]
C=lambda l,N,B:[i for i in l if i[-1]in N]or C([i+[(i[-1][0]+c,i[-1][1]+d)]for i in l for c,d in [(-1,0),(0,-1),(0,1),(1,0)]if all(1<abs(i[-1][0]+c-a)or 1<abs(i[-1][1]+d-b)for a,b in B)],N,B)
X,Y=len(G[0]),len(G)
N,M,B=[filter(list,[S(G,s,t,e,lambda a,b:0<=a<X and 0<=b<Y and Y*(a-s)+b-t>=0)for s in R(X)for t in R(Y)])[0][0]for e in["nemo","marlin","bruce"]]
s=N+M+min([C([[k]],N,B)[0]for k in M],key=lambda i:len(i))
print'\n'.join(''.join(G[y][x]if(x,y)in s else'.'for x in R(X))for y in R(Y))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.