La mia prigione è sicura?


58

Alla tua sfida viene fornito un input di un layout di prigione per capire se uno dei prigionieri può fuggire.

Ingresso

L'input può essere in qualsiasi formato ragionevole come una stringa, un array, un array di array, ecc. L'input sarà composto da tre caratteri, in questo caso #, Pe dallo spazio. L'input non conterrà necessariamente tutti e tre i caratteri.

  • #: Un muro
  • P: Un prigioniero
  • spazio: uno spazio vuoto

Un input di esempio sarà simile a:

#####
#   #
# P #
#   #
#####

Produzione

Un valore di verità / falsità sulla sicurezza della prigione. La prigione è sicura solo se può contenere tutti i prigionieri. Se un prigioniero può scappare, non è sicuro.

Un prigioniero può scappare se non è completamente chiuso da un muro. Un'unione diagonale è completamente chiusa.

Casi test

############# Truthy
# P #  P#   #
#   #   # P #
#############

############# Truthy
# P    P    #
#   #   # P #
#############

############# Falsey
# P #  P#   #
#   #   # P #
########## ##

####          Truthy
#   #
 #   #
  # P ####
  ####

P             Falsey

###           Falsey
# #
# #
### P

8
Ho la sensazione che questa sia una sfida duplicata o almeno simile. Buona sfida comunque.
John Dvorak,

2
@JanDvorak Potrebbe essere, ma con il mio Google Fu limitato non sono riuscito a trovare un duplicato.
TheLethalCoder

2
correlate (Riempi una griglia 2D)
Esolanging Fruit

3
Sarebbe bello avere esempi Falsey in cui sia necessario il movimento orizzontale e verticale per fuggire.
xnor

2
@tfbninja Non proprio un duplicato. Quello che chiede di provare a estrapolare il programma dai dati dati per determinare se la parola è nella casella. Questo è un riempimento BFS per vedere se ci sono spazi non chiusi che contengono valori contrassegnati.
HyperNeutrino

Risposte:


54

Lumache , 13 byte

!(t\P(o\ ),o~

Provalo online!

Stampa 0per carceri non sicure e la dimensione del riquadro di delimitazione dell'input per carceri sicure.

L'idea è quella di garantire che non possiamo trovare un percorso da una Pa una cella fuori limite ( ~) che si sposta solo ortogonalmente ( o) attraverso gli spazi. Si ttratta di un teletrasporto in modo che, indipendentemente da dove tentiamo la corrispondenza, cerca tutte le possibili posizioni iniziali per trovare a P.


23
Lo strumento giusto.
Jonathan Allan,

16

C # (.NET Core) , 485 480 474 470 421 408 byte

Lo strumento e l'approccio assolutamente sbagliato, ma comunque ...

  • 7 byte (e altro) salvati con i consigli utili di TheLethalCoder.
  • 4 byte salvati restituendo un numero intero.
  • Altri 4 byte salvati grazie (ancora una volta) a TheLethalCoder sostituendoli ' 'con 32nei confronti.
  • MOLTI byte salvati dal refactoring del codice.
  • 13 byte in più grazie a (indovina chi?) TheLethalCoder. :) Continuo a dimenticare i suoi consigli e continua a ricordarmeli.
m=>{var p='P';int a=m.Length,b=m[0].Length,i=0,j,x,y;var c=new System.Collections.Stack();for(;i<a;i++)for(j=0;j<b;j++)if(m[i][j]==p)c.Push(new[]{i,j});while(c.Count>0){var t=(int[])c.Pop();x=t[0];y=t[1];if(x<1|x>a-2|y<1|y>b-2)return 0;foreach(var v in new[]{-1,1}){var z=x>0&x<a-1&y>0&y<b-1;if(z&m[x+v][y]==32){m[x][y]=p;c.Push(new[]{x+v,y});}if(z&m[x][y+v]==32){m[x][y]=p;c.Push(new[]{x,y+v});}}}return 1;}

Provalo online!

Fondamentalmente espanderò le posizioni delle P ogni volta che uno spazio bianco è attorno fino a raggiungere (o meno) il bordo del layout.

Alcune licenze:

  • Uso a char[][]come input per il layout.
  • Restituisce 0come insicuro e 1sicuro.

Non puoi dare ulteriore input alla funzione in modo da poter assumere le dimensioni ... A meno che tu non riesca a trovare un meta post per convincermi altrimenti.
TheLethalCoder

1>0e 1<0sono più brevi di truee false.
TheLethalCoder

1
Può ==0diventare <1? Hai almeno 1 byte di spazio bianco irrilevante. Puoi rimuovere la new[]s? (Non sempre funziona ma a volte piace int[] n = {1,2,3};).
TheLethalCoder

1
{m[x][y]= p; c.Push(new[]->{m[x][y]=p;c.Push(new[]
TheLethalCoder

1
Puoi confrontare chars con ints, quindi credo che puoi sostituire il ==' 'to ==32per salvare i byte. Dovresti essere in grado di farlo anche su confronti simili.
TheLethalCoder

15

Perl 5 , 69 byte

-10 byte grazie a @Grimy .

-2 byte grazie a @Neil .

77 byte di codice + -p0flag.

/
/;$_=s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/s?redo:!/\A.*P|P.*\Z|^P|P$/m

Provalo online!

Alcune brevi spiegazioni:
l'idea è quella di mettere Povunque i prigionieri possano andare. Se ce ne Psono sulla prima / ultima riga o sulla prima / ultima colonna, i prigionieri possono andare lì e quindi fuggire, il che significa che la prigione non è sicura.
s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/ssostituisce uno spazio a destra o sotto a Pcon uno Po uno spazio a sinistra o sopra a P.
Infine, /\A.*P|P.*\Z|^P|P$/mcontrolla se una riga inizia o termina con a Po se è presente una Psulla prima o l'ultima riga.


approccio interessante usando regexps! (ma probabilmente MOLTO costoso quando lo spazio cresce)
Olivier Dulac il

In realtà, non è così inefficiente. In particolare, non richiede molto backtracking, non ci sono *o +, la corrispondenza più lunga che può fare è la dimensione di una linea ... Ora ovviamente se si confronta con un approccio più manuale, basato su array per esempio , quindi sì è abbastanza inefficiente!
Dada,

1
-6 byte fondendo le due sostituzioni: s/P(.{@{-}})? | (.{@{-}})?P/P$1$2P/s.
Grimmy,

1
-2 byte da golf sostituzione unito: s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/s.
Grimmy,

2
@Grimy molto bello il golf del regex! Grazie :)
Dada,

7

JavaScript (ES6), 134 133 byte

Accetta input come una matrice di matrici di caratteri. Restituisce 0(insicuro) o 1(sicuro).

f=a=>a.map((r,y)=>r.map((c,x)=>c>'O'&&[-1,1,0,0].map((X,i)=>(R=a[y+1-'1102'[i]])&&R[X+=x]?R[X]<'!'?R[o=2,X]=c:0:o=0)),o=1)|o&2?f(a):o

Casi test


La &&s può essere &?
TheLethalCoder

@TheLethalCoder Non il primo, ma il secondo può essere sostituito da |. Grazie!
Arnauld,

Non sapevo che l'operatore di spread lavorasse sulle stringhe. Freddo!
aebabis,

6

JavaScript (ES6), 121 byte

f=s=>s==(s=s.replace(eval('/( |P)([^]{'+s.search`
`+'})?(?!\\1)[ P]/'),'P$2P'))?!/^.*P|P.*$/.test(s)&!/^P|P$/m.test(s):f(s)

Accetta l'input come una stringa rettangolare delimitata da nuova riga. Restituisce 0 per non sicuro e 1 per sicuro. Sulla base della mia risposta a Detect Failing Castles , anche se sarebbe più efficiente testare un prigioniero fuggito ad ogni passo, piuttosto che una volta che avevano finito di esplorare la prigione.


2

Ottava, 64 55 byte

@(a,z=padarray(a,[1 1]))~nnz(bwfill(z==35,1,1,4)&z>35);

Provalo online!

o

Verifica tutti i casi di test!

Spiegazione:

z=padarray(a,[1 1])       %add a boundary(of 0s) around the scene
F = bwfill(z==35,1,1,4)   %flood fill the prison starting from the boundary
~nnz(F&z>35);             %if position of at least a prisoner  is filled then the prison is not secure 

2

APL (Dyalog Classic) , 40 byte

{⊃2≠(××{1⊃⌈/⍵,⍉⍵}⌺3 3)⍣≡(⌽1,⍉)⍣4'# '⍳⍵}

Provalo online!

'# '⍳⍵codificare '#', ' ', 'P'come 0 1 2

(⌽1,⍉)⍣4 circondare con 1s

(××{1⊃⌈/⍵,⍉⍵}⌺3 3)⍣≡ riempimento di inondazioni di celle diverse da zero

⊃2≠ non abbiamo un 2 in alto a sinistra?


1

Stax , 35 byte CP437

ä¬my■╡╤▲l@┤êr*⌠\¶ƒläå─▄¶√¿ [Uy⌠Só4↔

Provalo online!

Sicuramente il linguaggio del golf senza un interno per gestire la ricerca del percorso può fare anche questo!

Spiegazione

Utilizza il formato non compresso per spiegare.

zLz]Y+Mys+y+{{{" P|P ""PP"Rm}Y!My!Mgphh' =
zLz]Y+Mys+y+                                  Surround the original matrix with four borders of whitespaces
            {                      gp         Iterate until a fixed point is found, return the single fixed point
             {              }Y!               Store the block in register Y and execute it
              {" P|P ""PP"Rm                  For each row, flood every space adjacent to a P with P.
                               My!            Transpose the matrix and do the flooding again
                                     hh' =    The final matrix has a space on the upper left corner that has not been flooded by P 

1

SmileBASIC, 154 146 byte

Speravo che una risposta usando il riempimento di inondazione fosse più breve di così.

DEF S P
FOR J=0TO 1X=1Y=1FOR I=0TO LEN(P)-1GPSET X,Y,-(P[I]=="#")GPAINT X,Y,-1,-J*(P[I]>@A)X=X*(P[I]>"31")+1INC Y,X<2NEXT
NEXT?!GSPOIT(0,0)GCLS
END

Sostituisci 31con il carattere ASCII corrispondente.

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.