用跟随墙壁的蛇填充迷宫,直到被卡住


21

用蛇把迷宫填满(直到被卡住)。

蛇从给定的起点开始,指向EAST。它通过移动总是有墙壁或它的身体的一部分立即LEFT其头部(“的左手法则墙跟随 ”),直到它被卡住,因为它周围所有的头四个方向都被占用。(注意:卡住的蛇可能无法填满所有可到达的空间,但这不是目标!)

挑战

编写接受迷宫作为2D文本形式的输入的程序或函数:

  • 输入可以采用任何合理的格式:例如,字符串列表,带换行符的单个字符串,文件。
  • 迷宫有墙(“ #”),空白处(“ ”)和正好一个起点(“ o”)。
  • 您可以选择

    • 要么假设第一行和最后一行都是完整的墙;
    • 或假设每个输入都具有隐式的外层墙
  • 您可以假设起点在其正上方(北)具有一堵墙(或隐式墙),并且蛇可以在EAST或SOUTH方向上进行有效的起点移动。

  • 您可以假定文本中没有其他字符(如果需要输入,则换行符除外)。
  • 您可以假定所有行的长度都相同。

并打印/返回“填充的迷宫”作为输出,并附上蛇被卡住时的快照

  • 蛇的身体由>v<^指向其一段的位置的字符表示
  • 蛇的起点是其起点的方向(“ >”,除非必须立即转弯)或一个o字符(不需要保持一致)
  • 蛇的终点是一个o角色

计分

常规代码高尔夫:最短代码胜出

in:
#################################
#                    o          #
#                               #
#     ##       ###       ##     #
#    ##     ##     ##     ##    #
#    ##     ##     ##     ##    #
#    ##      ##   ##      ##    #
#   ##       ##   ##       ##   #
#   ##         ###         ##   #
#    ##       #####       ##    #
#    ##       #####       ##    #
#    ##        ###        ##    #
#     ##                 ##     #
#                               #
#                               #
#################################

out:
#################################
#>>>>>>>>>>>>>>>>>>>v>>>>>>>>>>v#
#^>>>>>>>>>>>>>>>>>v>>>>>>>>>>vv#
#^^   ##>>>>>>v###o>>>>>v##   vv#
#^^  ##>^   ##>>>>^##   >v##  vv#
#^^  ##^    ##     ##    v##  vv#
#^^  ##^     ##   ##     v##  vv#
#^^ ##>^     ##   ##     >v## vv#
#^^ ##^<       ###       v<## vv#
#^^  ##^      #####      v##  vv#
#^^  ##^      #####      v##  vv#
#^^  ##^<      ###      v<##  vv#
#^^   ##^<<<<<<<<<<<<<<<<##   vv#
#^^<<<<<<<<<<<<<<<<<<<<<<<<<<<<v#
#^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#
#################################

动画(出于说明目的):

在此处输入图片说明

编辑:请注意,如果有疑问,蛇应“保持其左手”在它已经在其上的墙壁上,跟随拐角,而不是跳到1个街区之外的墙壁上。

在此处输入图片说明

感谢乔纳森·艾伦(Jonathan Allan)提出来,感谢Draco18s提供上面的说明性快照。

其他例子

in:
####################
#               o# #  
#                ###
#                  #
#      ##          #
#                ###
####################

out:
####################
#>>>>>>>>>>>>>>vv# #
#^>>>>>>>>>>>>vvv###
#^^   v<<<o<<<<v>>v#
#^^<<<<##^<<<<<<v<<#
#^<<<<<<<<<<<<<<<###
####################
in:
####################
#         o    #####  
#              #####
#                  #
#                 ##
####################

out:
####################
#         >>>>v#####
#             v#####
#             >>>>o#
#                 ##
####################
in:
################
#o             #
#   ########## #
# #          # #
# #          # #
# #          # #
# #  #       # #
# #          # #
# #          # #
# #          # #
# ############ #
#              #
################

out:
################
#>>>>>>>>>>>>>v#
#>>v##########v#
#^#>>>>>>>>>v#v#
#^#>>>>>>>>vv#v#
#^#^>>>>>>vvv#v#
#^#^^#    vvv#v#
#^#^^o<<<<<vv#v#
#^#^^<<<<<<<v#v#
#^#^<<<<<<<<<#v#
#^############v#
#^<<<<<<<<<<<<<#
################

在GIF示例中,当它进入模式时,为什么不回头填充空白区域的其他部分?绝对有可能先左转然后再上,左再下然后再转回,但是蛇选择了直下。目标是用蛇填充尽可能多的空间,还是仅遵循“遇到墙时向右转,如果两次向右转则结束”的策略?
魔术章鱼缸

2
我不确定@MagicOctopusUrn在什么时候看到歧义。但是,为回答您的问题,目标是不填充尽可能多的空间。但是,算法(“墙跟随者”)不只是“向右转一次,或者如果不可能,则两次”:如果蛇发现自己的左侧没有墙,则必须向左转(保持“左”手”)
Nicola Sap

(对不起,我误读了您的算法概要)
Nicola Sap

2
// @乔纳:对。只有一条确定性的道路,而且它不是最优的。// @超值墨水:是的。@ jonathanallan我很难理解模棱两可,但可能只是我一个人。我的追墙算法版本是:保持方向,除非您再也没有障碍物了[先评估],在这种情况下,请向左转,或者碰到墙[评估后],在这种情况下,请右转。如果可能的话,或者游戏结束。
Nicola Sap

1
我必须剖析gif,以弄清楚最终状态为何如此。从最终显示的帧中看不出来,而是从之前的状态来看i.stack.imgur.com/kj67V.png我希望能对人们有所帮助。
Draco18s

Answers:


8

木炭94 68字节

F²⊞υSW¬⁼§υ⁰§υ±¹⊞υS≔⪫υ¶θPθ…θ⌕θo≔⁰θW№KV «≧⁺⊖⌕E³§KV⁺θκ θ✳§rdluθ§>v<^θ»o

在线尝试!链接是详细版本的代码。说明:

F²⊞υSW¬⁼§υ⁰§υ±¹⊞υS≔⪫υ¶θ

将输入插入字符串。可以通过使用不太方便的输入格式来避免这种情况。

Pθ…θ⌕θo

在不移动光标的情况下打印输入,然后o再次向上打印,以便光标在其下方结束。

≔⁰θ

初始化当前方向。

W№KV «

当在某个方向上仍有可用空间时,请重复进行。

≧⁺⊖⌕E³§KV⁺θκ θ

计算蛇是否可以向左转,或是否被迫向右转。该代码≦⊖θW¬⁼§KVθ ≦⊕θ也可用于相同的字节数,尽管它认为0向上而不是正确,所以其余代码需要进行调整。

✳§rdluθ§>v<^θ

在适当的方向上输出适当的身体角色。

»o

恢复头部。这也可以这样写,Po即打印头而不必每次通过循环都移动光标(但这允许对于相同的字节数隐式关闭循环)。


7

Python 2中273个 253 242字节

-11字节归功于ArBo

g=input()
d=0
t=lambda g,k=1:'\n'.join(map(''.join,zip(*g.split('\n')[::k])[::-k]))
h='o '
while 1:
 l,r=t(g,-1),t(g)
 if h in l:g=l;d-=1
 elif h in g:g=g.replace(h,'>v<^'[d%4]+'o')
 elif h in r:g=r;d+=1
 else:break
exec-d%4*'g=t(g);'
print g

在线尝试!

通过搜索字符串,如果在迷宫中,则将其'o '替换'[>v<^]o'为来进行工作。

还将对旋转的迷宫进行相同的检查,并在字符串不再存在时打印填充的迷宫。

该功能t=lambda g,k=1:'\n'.join(map(j,zip(*g.split('\n')[::k])[::-k]))用于旋转网格


3

果冻72 56字节

œṣ€⁾o j€ṛị“v<^>”;”oʋ,
UZ$ṛ¡+ƭ€Ɱ3r5¤ç/€ḟ$Ḣß$ṛ¹?
,0ÇZU$ṛ¡/

在线尝试!

一个完整的程序,将输入作为字符串列表,并返回带有最后一条蛇的字符串列表。注意,TIO上的页脚将单个换行符分隔的字符串转换为所需的输入,并在末尾恢复换行符。这仅仅是为了方便。

该解决方案在某种程度上受到@Rod的Python 2答案使用的方法的启发,尽管实现方式大不相同。


3

红宝石126118字节

滥用可节省-8个字节,+=而不是o在重新放置后手动进行搜索。

->s{d=[q=1,1+l=s=~/$/,-1,~l];i=s=~/o/;(s[i]=">v<^"[q];s[i+=d[q]]=?o)while q=[~-q%4,q,-~q%4].find{|e|s[i+d[e]]==' '};s}

在线尝试!


3

T-SQL查询2008年,373个 371 366字节

我有一个优先列表,总是向左,向右,向右滑动。我将优先级更改为始终向后,向左,向右,向右滑动。往后退一直会被阻止,因此除第一个滑行外,优先级仍然相同。通过最初将蛇掉下来(C = 4),它会在回弹时试图向上滑动。这个小特技为我节省了2个字节。因为我不需要在〜-〜-c%4中加1。

我插入了两个换行符以使其可读

DECLARE @ varchar(8000)=
'################
#o             #
#   ########## #
# #          # #
# #          # #
# #          # #
# #  #       # #
# #          # #
# #          # #
# #          # #
# ############ #
#              #
################';

WITH s as(SELECT 0i,4c,@ m 
UNION ALL
SELECT~-i,x,stuff(stuff(m,~-a+x/3*2+(x-3)%2*s,1,'o')
,a,1,char(59+x+~x%2*11*~x))FROM(SELECT
charindex(' ',replicate(stuff(substring(m,~-a,3),2,1,substring(m,a+~s,1))+
substring(m,a-~s,1)+'~',2),-~-~c%4)%5x,*FROM(SELECT*,charindex('o',m)a,charindex('
',M)S FROM S)Q)L
WHERE x>0)SELECT top 1m FROM s
ORDER BY i
OPTION(MAXRECURSION 0)

我必须进行一些小的调整才能在线执行此操作,发布的版本在MS-SQL服务器管理工​​作室中运行。

在MS-SQL Server Management Studio中执行之前按Ctrl-T,它将结果显示为文本。

在线尝试


2
我不知道这是如何工作的,但是我可以验证它是否有效。很棒的工作!
BradC

@BradC感谢您的确认和赞美。如今,SQL解决方案并没有获得太多关注。
t-clausen.dk

1

Python 3,343字节

import sys
X=0,1,0,-1
F,*Y=*X,0
L=3
g=[*map(list,sys.stdin.read().split("\n"))]
e=enumerate
r,c=[[r,c]for r,R in e(g)for c,C in e(R)if"o"==C][0]
while 1:
	if" "==g[r+X[L]][c+Y[L]]:F,L=L,~-L%4
	elif" "<g[r+X[F]][c+Y[F]]:
		if" "<g[r-X[L]][c-Y[L]]:g[r][c]="o";break
		L,F=F,-~F%4
	g[r][c]=">v<^"[F];r,c=r+X[F],c+Y[F]
for r in g:print("".join(r))

在线尝试!

-11字节归功于ArBo
--4字节归功于Jonathan Frech


您可以打高尔夫球的初始化XYFX=0,1,0,-1;F,*Y=*X,0如果我没有记错的话。另外,所import*花费的字节数要多于节省的字节数。
ArBo

@ArBo哦,我认为这可以节省一些大声笑。这也很聪明,谢谢!
HyperNeutrino

我认为您可以使用保存一个字节*g,=map(...)。并且可行sys.stdin.readlines()吗?
Andras Deak

1
或者,您可以通过假设为单行输入并使用来节省一些字节input()
Andras Deak

1
if C=="o"〜> if"o"==Cif g[r+X[L]][c+Y[L]]==" "elif g[r+X[F]][c+Y[F]]>" "if g[r-X[L]][c-Y[L]]>" "相应。
Jonathan Frech

1

05AB1E54 52 字节

[S¶¡øí3FDíø})J€»¼D¾èU¼.Δ.¼„o ©å}DÄiXqë®">^<v"¾è'o«.;

I / O都作为单个多行字符串。

在线尝试验证所有测试用例

说明:

[                      # Start an infinite loop:
 S                     #  Split the multi-line string into a list of characters
                       #  (which will use the implicit input in the first iteration)
  ¶¡                   #  Then split by newlines
    øí                 #  Rotate the matrix once clockwise
      3F               #  Loop 3 times:
        D              #   Create a copy of the matrix
         íø            #   And rotate this copy once counterclockwise
       })              #  After the loop: wrap all four matrices into a list
 J                     #  Join each inner-most character-list to string-lines again
  €»                   #  And join each inner list of lines by newlines again
    ¼                  #  Increase variable `c` by 1 (variable `c` is 0 by default)
     D¾<è              #  Index the updated variable `c` in a copy of the list of matrices
                       #  (note that indexing wraps around in 05AB1E)
         U             #  Pop and store it in variable `X`
    ¼                  #  Then increase variable `c` again
                     #  Find the first multi-line string in the list which is truthy for:
                     #   Decrease variable `c` by 1 first
        o             #   Push string "o "
           ©           #   Store this string in variable `®` (without popping)
            å          #   Check if the current multi-line string contains this "o "
    }D                 #  Duplicate the result (results in -1 if none were truthy/found)
      Äi               #  If no result was found:
        X              #   Push variable `X`
         q             #   And stop the program, after which this multi-line string of
                       #   variable `X` is output implicitly as result
       ë               #  Else:
         ">^<v"¾è      #   Get the `c`'th character in string ">^<v"
                       #   (note that indexing wraps around in 05AB1E)
                 'o«  '#   Append a trailing "o" to this character
        ®           .; #   And replace the first variable `®` ("o ") in the 
                       #   multi-line string with this

0

Pyth,161字节

J.zK[Z1Z_1)=Y+tKZVlJFTl@JNIq@@JNT\oA[NT;=N3=TZ#Iq@@J+G@KN+H@YNd=TN=N%tN4.?In@@J+G@KT+H@YTdIn@@J-G@KN-H@YNd XJGX@JGH\oB=NT=T%hT4)) XJGX@JGH@">v<^"TA(+G@KT+H@YT;jJ

在线尝试!

HyperNeutrino的Python 3解决方案的端口。既然我已经完成它,我在想也许我应该移植Rod的Python 2解决方案,但是我已经花了太多时间在此上。

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.