Il labirinto può essere risolto?


20

Il puzzle

  • Stampa 0 se un labirinto n * m non può essere risolto
  • Stampa 1 se un labirinto n * m può essere risolto (in 1 o più modi)

(quindi non sto chiedendo percorsi ma se è possibile risolvere !!!)

Array di input (2d):

[[0,0,0,0,0,0,1],[0,0,0,0,0,1,0],[0,0,0,0,1,0,0],[1,0,0,0,0,0,0]]

XXXXXXXXX
XS     XX
X     X X
X    X  X
XX     FX
XXXXXXXXX

0 = can pass through
1 = can not pass trough
[0][n] is the last block of the first line
[m][0] is the first block of the last line

Regola La posizione iniziale è 0,0 e la posizione finale è n, m Puoi muoverti solo in orizzontale e in verticale Il codice più corto vince


L'input dovrebbe essere una stringa o un array?
apsillers,

3
Se c'è un 1 (muro) in (n, m) il codice dovrebbe restituire 0?
trichoplax,

3
(Lo stesso vale per un muro a (0,0)?)
Martin Ender il

3
Dici che è un labirinto × m, ma l'indicizzazione implica che è un labirinto (n + 1) × (m + 1).
Nick Matteo,

3
Non vedo l'ora di trovare la soluzione regex =)
flawr, il

Risposte:


7

CJam, 42 41 39 36 35 byte

Wq3>~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=

Basato sulle idee in questa risposta .

4 byte grazie a Optimizer.

Formato di input:

[[0 0 0 0 0 0 1] [0 0 0 0 0 1 0] [0 0 0 0 1 0 0] [1 0 0 0 0 0 0]]

@Optimizer Grazie per quello. Ma poi ho trovato un modo più breve ...
jimmy23013,

1
q2Wts~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=- 36. Sebbene si presuma che i primi tre caratteri dell'input siano[[0
Ottimizzatore

7

Dyalog APL, 27 personaggi

⊃⌽∨.∧⍨⍣≡1≥+/¨|∘.-⍨,(~×⍳∘⍴)⎕

input valutato. APL distingue tra una matrice e un vettore di vettori. Questo programma presuppone che l'ingresso sia una matrice.

(~×⍳∘⍴)Aè un fork equivalente a (~A) × ⍳⍴A. È necessario per evitare di menzionare due volte o introdurre una variabile.

⍴Aè la forma di A. Per una matrice 4 per 7 la forma è 4 7.

è il generatore di indice. ⍳4lo è 1 2 3 4. ⍳4 7sono i vettori (1 1)(1 2)...(4 7)disposti in una matrice 4 per 7.

~Alancia i bit di A.

×moltiplicando ⍳⍴Aper i bit capovolti, conserviamo le coordinate di tutte le celle libere e trasformiamo tutte le pareti in 0 0.

,ravviva la matrice delle coppie di coordinate, cioè la linearizza in un vettore. In questo caso il vettore sarà composto da coppie.

∘.-⍨Ao A∘.-Asottrae gli elementi di Apairwise. Si noti che qui gli elementi di Asono essi stessi coppie.

| valore assoluto

+/¨somma ogni coppia di valori assoluti. Questo ci dà le distanze della griglia tra ogni coppia di celle nel labirinto, tranne che per i muri.

1≥siamo interessati solo nei vicini a una distanza non superiore a 1, questo esclude anche i muri. Ora abbiamo una matrice di adiacenza di un grafico.

∨.∧⍨⍣≡ Floyd - L'algoritmo di chiusura transitiva di Warshall

(f⍣n)A(non utilizzato qui) dove nè un numero intero è l'operatore di potenza. Essa si applica fa A nvolte: f f ... f A.

(f⍣g)Adove gè una funzione, è l'operatore punto fisso, noto anche come "limite di potenza". Continua a calcolare la serie A, f A, f f A, ... fino a quando ((f⍣i)A) g ((f⍣(i+1))A)ritorna vero per alcuni i. In questo caso usiamo match ( ) come g.

∨.∧⍨Ao A∨.∧Aè un passo nell'algoritmo di Floyd. f.gè una generalizzazione della moltiplicazione di matrici ( +.×), qui usiamo congiunzione ( ) e disjunction ( ) al posto di +e ×.

⊃⌽ Dopo ⍣≡aver applicato il passaggio abbastanza volte e raggiunto uno stato stabile, dobbiamo cercare l'angolo in alto a destra della matrice per ottenere il risultato, quindi capovolgilo ( ) e prendiamo il primo elemento in alto a sinistra ( ).

Visualizzazione dei ⍣≡passi


5

Python, 164 byte

def s(a):
 d=[(0,0)]
 while d:i,j=d.pop();a[i][j]=2;d+=[(x,y)for x,y in[(i-1,j),(i,j-1),(i+1,j),(i,j+1)]if len(a[0])>y>-1<x<len(a)and a[x][y]<1]
 return a[-1][-1]>1

Ero riluttante a postare questo perché è praticamente il modo in cui normalmente farei il riempimento di alluvione, solo leggermente golfato. Ma eccolo qui comunque.


4

Perl, 73 byte

69 byte di codice + 4 byte per -n0E(non sono sicuro di come siano stati contati i tag nel 2014, quindi li ho contati per 4 anziché 2, ma non importa molto).

/.*/;s/(^0|A)(.{@{+}})?0/A$2A/s||s/0(.{@{+}})?A/A$1A/s?redo:say/A$/+0

Provalo online! (e se sostituisci la 1111011linea con 1111111, il labirinto non è più risolvibile e l'output sarà 0invece di 1: Provalo online! )

spiegazioni:

Questo codice troverà tutte le celle raggiungibili del labirinto (e le contrassegnerà con una A): se una cella tocca una cella contrassegnata con una A, è raggiungibile e la contrassegniamo anche con una A; e lo facciamo di nuovo ( redo). Questo è fatto grazie a due regex: s/(^0|A)(.{@{+}})?0/A$2A/scontrolla se uno spazio è a destra o in fondo a a A, mentre s/0(.{@{+}})?A/A$1A/scontrolla se uno spazio è a sinistra o in cima a a A. Alla fine, se l'ultima cella contiene un indice dell'indice della fine della prima riga, che risulta essere la dimensione di una riga, che consente l'uso da utilizzare per abbinare esattamente tutti i caratteri che ci sono su una riga. (A è raggiungibile, altrimenti non lo è (questo è ciò che say/A$/+0controlla; +0è qui per assicurarsi che il risultato sarà 0o 1invece di stringa vuota e 1).
Si noti che /.*/corrisponderà a un'intera riga, impostando così@+.{@{+}}@{+} è equivalente a @+, ma solo il primo può essere utilizzato in regex)


Per questo caso di test , il tuo codice considera risolvibile il labirinto anche se la posizione finale è 1.
Jitse

@Jitse Buona cattura. In realtà, è stato perché i collegamenti TIO non utilizzavano il codice giusto (suppongo fosse una versione precedente e non l'ho individuato). La risposta è ancora valida e ho aggiornato i collegamenti TIO. Il tuo esempio funziona quindi bene: provalo online!
Dada,

Oh giusto! Grazie per il chiarimento, mi piace questo approccio.
Jitse il

@Jitse grazie, è uno dei miei campi da golf preferiti :)
Dada il

3

Rubino, 133 130 129 caratteri

a=eval gets
f=->x,y{a[x][y]=1
[[-1,0],[1,0],[0,-1],[0,1]].map{|o|d,e=x+o[0],y+o[1]
f[d,e]if a[d]&&a[d][e]==0}}
f[0,0]
p a[-1][-1]

Ingresso su STDIN, uscite 1o 0su STDOUT.

Fastidiosamente lungo. Fa semplicemente un pieno di 1s da(0, 0) , quindi verifica se il quadrato "end" è a 1.


Tratterà il labirinto come risolvibile se contiene già un 1 a (n, m)?
trichoplax,

2

Java, 418 byte

import java.util.Scanner;public class Solvable{static int w,h;public static void main(String[] a){String[]i=new Scanner(System.in).nextLine().split(";");h=i.length+2;w=i[0].length()+2;int[]m=new int[w * h];for(int x=1;x<w-1;x++)for(int y=1;y<h-1;y++)m[y*w+x]=i[y-1].charAt(x-1)<'.'?0:1;f(m,w+1);System.out.println(m[w*h-w-2]>0?0:1);}static void f(int[]m,int i){if(m[i]>0){m[i]--;f(m,i-1);f(m,i+1);f(m,i-w);f(m,i+w);}}}

Il mio primo codice golf. Non so perché ho scelto Java - è così male per giocare a golf xD

Un labirinto di esempio verrebbe immesso tramite stdin in questo modo:

......#;.....#.;....#..;#......

1
Consiglio del professionista: assegna alla tua classe un carattere lungo un carattere, elimina lo spazio tra String[]e ae prendi input dagli argomenti della riga di comando anziché da StdIn, che è consentito.
Pavel,

1

Python 184 188

def f(a,x=0,y=0,h=[]):s=h+[[x,y]];X,Y=len(a[0]),len(a);return([x,y]in h)==(x>=X)==(y>=Y)==(x<0)==(y<0)==a[y][x]<(x==X-1and y==Y-1or f(a,x-1,y,s)|f(a,x+1,y,s)|f(a,x,y-1,s)|f(a,x,y+1,s))

Questo è diventato molto più lungo di quanto pensassi :( Comunque, aggiungerò una spiegazione una volta che non posso più giocare a golf.


1

J, 75 caratteri

Accensione della matrice di adiacenza (molto tempo e memoria inefficiente). (Si chiama powering in inglese?)

   ({.@{:@(+./ .*.^:_~)@(+:/~@,*2>(>@[+/@:|@:->@])"0/~@,@(i.@#<@,"0/i.@#@|:)))

Alcuni casi di test:

   m1=. 0 0 0 0 0 0 1,. 0 0 0 0 0 1 0,.  0 0 0 0 1 0 0,. 1 0 0 0 0 0 0
   m2=. 0 1 1 ,. 0 0 0
   m3=. 0 1 0 ,. 1 1 0
   m4=. 0 1 1 0 ,. 0 0 1 0
   ({.@{:@(+./ .*.^:_~)@(+:/~@,*2>(>@[+/@:|@:->@])"0/~@,@(i.@#<@,"0/i.@#@|:))) every m1;m2;m3;m4
1 1 0 0


0

Python 3 , 184 byte

f=lambda m,x=0,y=0,n=0:n<len(m)*len(m[0])and m[x][y]<1and((x,y)==(len(m)-1,len(m[0])-1)or any(0<=i<len(m)and 0<=j<len(m[0])and f(m,i,j,n+1)for i,j in[(x-1,y),(x,y-1),(x+1,y),(x,y+1)]))

Provalo online!

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.