เรือนจำของฉันปลอดภัยหรือไม่?


58

ความท้าทายของคุณได้รับการป้อนข้อมูลของรูปแบบเรือนจำเพื่อกำหนดว่านักโทษคนใดสามารถหลบหนี

อินพุต

ป้อนข้อมูลอาจจะอยู่ในรูปแบบที่เหมาะสมใด ๆ เช่นสตริงอาร์เรย์อาร์เรย์ของอาร์เรย์ ฯลฯ การป้อนข้อมูลจะประกอบด้วยสามตัวละครในกรณีนี้#, Pและพื้นที่ อินพุตไม่จำเป็นต้องมีอักขระทั้งสามตัว

  • #: ผนัง
  • P: นักโทษ
  • พื้นที่: พื้นที่ว่าง

ตัวอย่างอินพุตจะมีลักษณะดังนี้:

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

เอาท์พุต

คุณค่าของความจริง / ความเท็จว่าเรือนจำนั้นปลอดภัยหรือไม่ คุกมีความปลอดภัย แต่ถ้ามันสามารถถือทั้งหมดของนักโทษ หากนักโทษคนใดสามารถหลบหนีได้ก็จะไม่ปลอดภัย

นักโทษสามารถหลบหนีได้หากไม่มีกำแพงล้อมรอบอย่างสมบูรณ์ การรวมเส้นทแยงมุมถูกปิดล้อมอย่างสมบูรณ์

กรณีทดสอบ

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

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

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

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

P             Falsey

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

8
ฉันมีความรู้สึกว่านี่เป็นสิ่งที่ซ้ำซ้อนหรืออย่างน้อยก็เป็นความท้าทายที่คล้ายกัน ความท้าทายที่ดีต่อไป
John Dvorak

2
@JanDvorak อาจเป็นได้ แต่ด้วย Google Fu แบบ จำกัด ของฉันฉันไม่สามารถหาข้อมูลซ้ำได้
TheLethalCoder


3
มันจะเป็นการดีถ้ามีตัวอย่างของ Falsey ที่ต้องเคลื่อนที่ทั้งแนวนอนและแนวตั้งเพื่อหลบหนี
xnor

2
@tfbninja ไม่ซ้ำกันจริงๆ สิ่งนั้นขอให้พยายามให้โปรแกรมคาดการณ์จากข้อมูลที่กำหนดเพื่อพิจารณาว่าคำนั้นอยู่ในกล่องหรือไม่ อันนี้เป็น BFS ท่วมท้นเพื่อดูว่ามีช่องว่างที่ไม่ได้เคลือบไว้ถือค่าทำเครื่องหมาย
HyperNeutrino

คำตอบ:


54

หอยทาก 13 ไบต์

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

ลองออนไลน์!

พิมพ์0สำหรับเรือนจำที่ไม่ปลอดภัยและขนาดของช่องสำหรับใส่ขอบเขตของเรือนจำที่ปลอดภัย

แนวคิดคือเพื่อให้แน่ใจว่าเราไม่สามารถหาเส้นทางจาก a Pไปยังนอกขอบเขตเซลล์ ( ~) ย้ายเฉพาะ orthogonally ( o) ผ่านช่องว่าง คือส่งผ่านทางไกลเพื่อให้คำนึงถึงการที่เราพยายามที่การแข่งขันก็พยายามที่ตำแหน่งเริ่มต้นที่เป็นไปได้ทั้งหมดที่จะหาtP


23
เครื่องมือที่เหมาะสม
Jonathan Allan

16

C # (.NET Core) , 485 480 474 470 421 408 ไบต์

เครื่องมือและวิธีการที่ผิดอย่างแน่นอน แต่กระนั้น ...

  • บันทึก 7 ไบต์ (และอื่น ๆ ) ด้วยคำแนะนำที่เป็นประโยชน์จาก TheLethalCoder
  • บันทึกได้ 4 ไบต์โดยส่งคืนจำนวนเต็ม
  • บันทึกอีก 4 ไบต์ขอบคุณ TheLethalCoder อีกครั้งโดยการแทนที่' 'ด้วย32การเปรียบเทียบ
  • จำนวนไบต์ที่บันทึกไว้โดยการเปลี่ยนรหัสอีกครั้ง
  • 13 ไบต์เพิ่มเติมขอบคุณ (เดาว่าใคร?) TheLethalCoder :) ฉันลืมเคล็ดลับของเขาต่อไปและเขาเตือนฉันต่อไปเรื่อย ๆ
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;}

ลองออนไลน์!

โดยทั่วไปฉันขยายตำแหน่งของ P ทุกครั้งที่มีพื้นที่สีขาวอยู่รอบ ๆ จนกว่าจะถึง (หรือไม่) เส้นขอบของเค้าโครง

ใบอนุญาตบางส่วน:

  • ฉันใช้char[][]เป็นอินพุตสำหรับโครงร่าง
  • ส่งคืน0อย่างไม่ปลอดภัยและ1ปลอดภัย

คุณไม่สามารถใส่ฟังก์ชั่นพิเศษเพื่อให้คุณสามารถสันนิษฐานได้ว่ามิติข้อมูล ... เว้นแต่คุณจะพบเมตาโพสต์เพื่อชักชวนให้ฉันเป็นอย่างอื่น
TheLethalCoder

1>0และ1<0จะสั้นกว่าและtrue false
TheLethalCoder

1
สามารถ==0กลายเป็น<1? คุณมีช่องว่างที่ไม่เกี่ยวข้องอย่างน้อย 1 ไบต์ คุณสามารถลบnew[]s? (อาจไม่ได้ผลเสมอไป แต่บางครั้งก็ไม่ชอบint[] n = {1,2,3};)
TheLethalCoder

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

1
คุณสามารถเปรียบเทียบcharเพื่อints ดังนั้นผมเชื่อว่าคุณสามารถแทนที่==' 'เพื่อ==32ที่จะบันทึกไบต์ คุณควรทำสิ่งนี้ในการเปรียบเทียบที่คล้ายกันเช่นกัน
TheLethalCoder

15

Perl 5 , 69 ไบต์

-10 ไบต์ขอบคุณที่@Grimy

-2 ไบต์ขอบคุณที่@Neil

77 ไบต์ของรหัส + -p0ธง

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

ลองออนไลน์!

บางสั้นคำอธิบาย:
ความคิดที่จะใส่Pทุกนักโทษสามารถไป หากมีPอยู่ในบรรทัดแรก / สุดท้ายหรือคอลัมน์แรก / สุดท้ายจากนั้นนักโทษสามารถไปที่นั่นและเพื่อหลบหนีซึ่งหมายความว่าคุกไม่ปลอดภัย
s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/sแทนที่พื้นที่บนขวาของหรือตะโกนPด้วยหรือพื้นที่ทางด้านซ้ายหรือด้านบนของที่P สุดท้ายตรวจสอบว่าบรรทัดเริ่มต้นหรือลงท้ายด้วย a หรือไม่หรือถ้ามีบรรทัดแรกหรือบรรทัดสุดท้ายP
/\A.*P|P.*\Z|^P|P$/mPP


วิธีการที่ยอดเยี่ยมโดยใช้ regexps! (แต่อาจมีราคาแพงมากเมื่อพื้นที่เติบโต)
Olivier Dulac

อันที่จริงก็ไม่ได้ว่าไม่มีประสิทธิภาพ โดยเฉพาะอย่างยิ่งมันไม่จำเป็นต้องมีการย้อนรอยจำนวนมากไม่มี*หรือ+การจับคู่ที่ยาวที่สุดที่สามารถทำได้คือขนาดของเส้น ... ตอนนี้แน่นอนถ้าคุณเปรียบเทียบกับแนวทางเพิ่มเติมด้วยตนเองขึ้นอยู่กับอาร์เรย์เช่น ใช่แล้วมันค่อนข้างไม่มีประสิทธิภาพ!
Dada

1
ไบต์ -6 s/P(.{@{-}})? | (.{@{-}})?P/P$1$2P/sโดยการผสานสองแทน:
Grimmy

1
-2 ไบต์โดยการเล่นกอล์ฟการเปลี่ยนตัวที่ผสาน: s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/s.
Grimmy

2
@Grimy การเล่นกอล์ฟที่ดีมากของ regex! ขอบคุณ :)
Dada

7

JavaScript (ES6), 134 133 ไบต์

รับอินพุตเป็นอาร์เรย์ของอักขระ ส่งคืน0(ไม่ปลอดภัย) หรือ1(ปลอดภัย)

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

กรณีทดสอบ


สามารถ&&s เพียง&?
TheLethalCoder

@TheLethalCoder ไม่ใช่คนแรก แต่คนที่สองสามารถแทนที่|ได้ ขอบคุณ!
Arnauld

ไม่ทราบว่าผู้ประกอบการแพร่กระจายทำงานบนสตริง เย็น!
aebabis

6

JavaScript (ES6), 121 ไบต์

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)

รับอินพุตเป็นสตริงสี่เหลี่ยมที่คั่นด้วยบรรทัดใหม่ ส่งคืน 0 สำหรับที่ไม่ปลอดภัยและ 1 เพื่อความปลอดภัย จากคำตอบของฉันต่อDetect Failing Castlesถึงแม้ว่ามันจะมีประสิทธิภาพมากกว่าในการทดสอบนักโทษที่หลบหนีในแต่ละขั้นตอนมากกว่าที่พวกเขาจะสำรวจคุกเสร็จแล้ว


2

ระดับเสียงคู่, 64 55 ไบต์

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

ลองออนไลน์!

หรือ

ตรวจสอบกรณีทดสอบทั้งหมด!

คำอธิบาย:

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 ไบต์

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

ลองออนไลน์!

'# '⍳⍵เข้ารหัส'#', ' ', 'P'เป็น 0 1 2

(⌽1,⍉)⍣4 ล้อมรอบด้วย 1 วินาที

(××{1⊃⌈/⍵,⍉⍵}⌺3 3)⍣≡ การเติมเต็มน้ำท่วมสูงสุดของเพื่อนบ้านที่ไม่ใช่เซลล์

⊃2≠ เราไม่มี 2 ที่มุมบนซ้ายหรือไม่?


1

Stax , 35 ไบต์CP437

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

ลองออนไลน์!

การเล่นกอล์ฟโดยไม่ใช้ภาษาในการจัดการค้นหาเส้นทางสามารถทำได้เช่นกัน!

คำอธิบาย

ใช้รูปแบบที่คลายการแพคเพื่ออธิบาย

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 ไบต์

ฉันหวังว่าคำตอบโดยใช้การเติมน้ำท่วมจะสั้นกว่านี้

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

แทนที่31ด้วยอักขระ ASCII ที่สอดคล้องกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.