Apakah penjara saya aman?


58

Tantangan Anda diberi masukan tata letak penjara untuk mengetahui apakah ada tahanan yang bisa melarikan diri.

Memasukkan

Input mungkin dalam format yang wajar seperti string, array, array array, dll. Input akan terdiri dari tiga karakter, dalam hal ini #, Pdan spasi. Input tidak harus mengandung ketiga karakter.

  • #: Dinding
  • P: Seorang tahanan
  • ruang: Ruang kosong

Contoh input akan terlihat seperti:

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

Keluaran

Nilai kebenaran / kepalsuan dari apakah penjara itu aman atau tidak. Penjara hanya aman jika bisa menahan semua tahanan. Jika ada tahanan yang bisa melarikan diri, itu tidak aman.

Seorang tahanan dapat melarikan diri jika mereka tidak sepenuhnya tertutup oleh tembok. Sambungan diagonal tertutup sepenuhnya.

Uji kasus

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

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

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

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

P             Falsey

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

8
Saya merasa ini adalah duplikat atau setidaknya tantangan serupa. Lagian tantangan bagus.
John Dvorak

2
@ JanDvorak Mungkin tapi dengan Google Fu terbatas saya, saya tidak dapat menemukan duplikat.
TheLethalCoder

2
terkait (Flood-fill a 2D grid)
Buah Esolanging

3
Akan lebih baik untuk memiliki contoh Falsey di mana gerakan horisontal dan vertikal diperlukan untuk melarikan diri.
xnor

2
@ tfbninja Bukan duplikat. Yang satu meminta untuk mencoba membuat program mengekstrapolasi dari data yang diberikan untuk menentukan apakah kata itu ada di dalam kotak. Yang ini adalah BFS floodfill untuk melihat apakah ada ruang tertutup yang menyimpan nilai yang ditandai.
HyperNeutrino

Jawaban:


54

Siput , 13 byte

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

Cobalah online!

Cetakan 0untuk penjara yang tidak aman dan ukuran kotak pembatas input untuk penjara yang aman.

Idenya adalah untuk memastikan bahwa kita tidak dapat menemukan jalur dari Psel ke batas ( ~) hanya bergerak secara ortogonal ( o) melalui ruang. Ini tadalah teleport sehingga di mana pun kami mencoba pertandingan, ia mencoba semua posisi awal yang mungkin untuk menemukan a P.


23
Alat yang tepat.
Jonathan Allan

16

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

Alat dan pendekatan yang benar-benar salah, tapi tetap saja ...

  • 7 byte (dan banyak lagi) disimpan dengan tips bermanfaat dari TheLethalCoder.
  • 4 byte disimpan dengan mengembalikan integer.
  • 4 byte lagi disimpan terima kasih (sekali lagi) ke TheLethalCoder dengan mengganti ' 'dengan 32perbandingan.
  • BANYAK byte disimpan oleh refactoring kode.
  • 13 byte lagi berkat (coba tebak siapa?) TheLethalCoder. :) Saya selalu lupa tipsnya dan dia terus mengingatkan saya mereka.
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;}

Cobalah online!

Pada dasarnya saya memperluas posisi P setiap kali ada ruang putih di sekitar sampai mencapai (atau tidak) perbatasan tata letak.

Beberapa lisensi:

  • Saya menggunakan char[][]input sebagai tata letak.
  • Kembali 0sebagai tidak aman dan 1aman.

Anda tidak dapat mengambil input tambahan ke fungsi sehingga Anda dapat mengasumsikan dimensi ... Kecuali jika Anda dapat menemukan posting meta untuk membujuk saya sebaliknya.
TheLethalCoder

1>0dan 1<0lebih pendek dari truedan false.
TheLethalCoder

1
Dapat ==0menjadi <1? Anda memiliki setidaknya 1 byte spasi kosong yang tidak relevan. Bisakah Anda menghapus new[]s? (Tidak selalu bekerja tetapi terkadang suka di int[] n = {1,2,3};).
TheLethalCoder

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

1
Anda dapat membandingkan chars dengan ints jadi saya percaya Anda dapat mengganti ==' 'to ==32untuk menyimpan byte. Anda harus dapat melakukan ini pada perbandingan serupa juga.
TheLethalCoder

15

Perl 5 , 69 byte

-10 byte terima kasih kepada @Grimy .

-2 byte terima kasih kepada @Neil .

77 byte kode + -p0bendera.

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

Cobalah online!

Beberapa penjelasan singkat :
Idenya adalah untuk menempatkan ke Pmana-mana tahanan bisa pergi. Jika ada yang Pberada di baris pertama / terakhir, atau kolom pertama / terakhir, maka tahanan dapat pergi ke sana dan kemudian melarikan diri, yang berarti penjara tidak aman.
s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/smenggantikan spasi di sebelah kanan atau di bawah a Pdengan P, atau spasi di sebelah kiri atau di atas a P.
Terakhir, /\A.*P|P.*\Z|^P|P$/mperiksa apakah sebuah baris dimulai atau diakhiri dengan P,, atau ada Pbaris pertama atau terakhir.


pendekatan keren menggunakan regexps! (tapi mungkin SANGAT mahal ketika ruang tumbuh)
Olivier Dulac

Sebenarnya, itu bukan yang tidak efisien. Secara khusus, itu tidak memerlukan banyak backtracking, tidak ada *atau +, pertandingan terlama yang bisa dilakukan adalah ukuran garis ... Sekarang tentu saja jika Anda membandingkan dengan pendekatan yang lebih manual, berdasarkan array misalnya , maka ya itu cukup tidak efisien!
Dada

1
Byte -6 dengan menggabungkan dua pergantian pemain: s/P(.{@{-}})? | (.{@{-}})?P/P$1$2P/s.
Grimmy

1
-2 byte dengan bermain golf substitusi gabungan: s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/s.
Grimmy

2
@Grimy golf yang sangat bagus dari regex! Terima kasih :)
Dada

7

JavaScript (ES6), 134 133 byte

Mengambil input sebagai array array karakter. Pengembalian 0(tidak aman) atau 1(aman).

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

Uji kasus


Bisakah ini &&terjadi &?
TheLethalCoder

@TheLethalCoder Bukan yang pertama, tetapi yang kedua bisa diganti |. Terima kasih!
Arnauld

Tidak tahu operator spread bekerja pada string. Keren!
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)

Mengambil input sebagai string persegi panjang terbatas-baris baru. Mengembalikan 0 untuk tidak aman dan 1 untuk aman. Berdasarkan jawaban saya untuk Detect Fail Castles , meskipun akan lebih efisien untuk menguji tahanan yang melarikan diri di setiap langkah, daripada setelah mereka selesai menjelajahi penjara.


2

Oktaf, 64 55 byte

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

Cobalah online!

atau

Verifikasi semua kasus uji!

Penjelasan:

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'# '⍳⍵}

Cobalah online!

'# '⍳⍵mengkodekan '#', ' ', 'P'sebagai 0 1 2

(⌽1,⍉)⍣4 dikelilingi dengan 1s

(××{1⊃⌈/⍵,⍉⍵}⌺3 3)⍣≡ max-of-tetangga mengisi sel-sel yang bukan nol

⊃2≠ apakah kita tidak memiliki angka 2 di kiri atas?


1

Stax , 35 byte CP437

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

Cobalah online!

Tentunya bahasa golf tanpa internal untuk menangani pencarian jalan dapat melakukan ini juga!

Penjelasan

Menggunakan format yang tidak dibongkar untuk menjelaskan.

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

Saya berharap jawaban menggunakan mengisi banjir akan lebih pendek dari ini.

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

Ganti 31dengan karakter ASCII yang sesuai.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.