我的监狱安全吗?


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

2
相关(洪水填充2D网格)
Esolanging Fruit

3
最好有Falsey示例,其中水平和垂直运动都需要逃逸。
xnor

2
@tfbninja并不是真的重复。那就是要求尝试让程序从给定的数据中推断出来,以确定单词是否在框中。这是BFS泛洪,以查看是否有未封闭的空间保存有标记的值。
HyperNeutrino

Answers:


54

蜗牛,13字节

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

在线尝试!

打印0不安全的监狱,并输入安全监狱的输入框的大小。

这样做的目的是确保我们找不到从a P到越界像元(~)的路径,该像元仅o通过空间正交()移动。在t这样不管我们尝试匹配它会尝试所有可能的起始位置找到一个瞬移P


23
正确的工具。
乔纳森·艾伦,

16

C#(.NET核心)485个480 474 470 421 408字节

绝对错误的工具和方法,但是...

  • 使用TheLethalCoder的有用技巧保存了7个字节(或更多)。
  • 返回一个整数可节省4个字节。
  • 通过在比较中用代替' ',这(再次)感谢TheLethalCoder,节省了4个字节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的位置,直到它到达(或不到达)布局的边界。

一些许可证:

  • 我使用a char[][]作为布局的输入。
  • 0以不安全且1安全的方式返回。

您不能对函数进行额外的输入,因此可以假定尺寸...除非您可以找到一个能说服我的元文章。
TheLethalCoder

1>0并且1<0true和短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
您可以比较chars到int这么相信你可以更换==' ',以==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将a右边或下面的空格替换为Pa P,或将a左边或上方的空格替换P
最后,/\A.*P|P.*\Z|^P|P$/m检查一行是否以开头或结尾P,或者P第一行或最后一行是否有。


使用正则表达式的好方法!(但随着空间的增长,可能会非常昂贵)
Olivier Dulac

实际上,它并不是那么低效。特别是,它不需要很多回溯,不需要*+,它可以做的最长匹配是一行的大小...现在,当然,如果您将比较手动的方法与基于数组的方法进行比较, ,那么是的,效率很低!
达达

1
通过合并两个替换来组成-6个字节:s/P(.{@{-}})? | (.{@{-}})?P/P$1$2P/s
Grimy

1
-2个字节,通过合并合并替换:s/(P| )(.{@{-}})?(?!\1)(?1)/P$2P/s
Grimy

2
@肮脏的正则表达式打高尔夫球非常好!谢谢:)
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

测试用例


在能&&作个&
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(表示安全)。根据我对“ 检测失败的城堡”的回答,尽管在每一步测试逃脱的囚犯都比在他们完成对监狱的探索之后更有效地测试。


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 1s环绕

(××{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字符。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.