文字迷宫求解器


14

给定stdin上的迷宫和入口点,编写一个程序,在stdout上打印到出口的路径。只要您的程序不会为每个迷宫生成平凡的路径(穿过迷宫中的每个点),任何路径都是可以接受的。

在输入中,墙壁用a标记,#入口点用a 标记@。您可以使用任何字符在输出中绘制迷宫和路径,只要它们完全不同即可。

您可以假设:

  • 入口和出口点在输入的边缘
  • 输入的每一行都具有相同的长度
  • 迷宫可解且无循环
  • 只有一个出口

最短的(Unicode)字符计数解决方案获胜。

例子

(请注意,输入用空格填充)

####   
#  #   
@ #####
#     #
#      
#######

####
#  #
@*#####
#*    #
#******
#######

### ###################
###         #         #
##  #########      #  #
 #             #####  #
 ###############   #@##

###*###################
###*********#*********#
## *#########*     # *#
 # *********** #####**#
 ###############   #@##

我也可以为端点添加字符吗?这将使我的程序更容易知道何时结束。
彼得·奥尔森

@彼得的玉米:当然。您不必使用相同的字符来绘制整个路径,而只需将其与输出的其余部分区分开即可。
Lowjacker 2011年

Answers:


5

Ruby 1.9,244个字符

l=*$<
i=l*""
e=[]
d=[1,-1,x=l[0].size,-x]
r=[f=9e9]*s=x*b=l.size;r[i=~/@/]=0
r.map{i.gsub(/ /){r[p=$`.size]=d.map{|u|p>-u&&r[u+p]||f}.min+1;e<<p if p%x%~-~-x*(p/-~x%~-b)<1}}
r[g=e.find{|i|r[i]<f}].times{i[g]=?*;g+=d.find{|l|r[g]>r[g+l]}}
puts i

两个示例的输出:

####   
#  #   
@*#####
#*    #
#******
#######

###*###################
###*        #     *** #
## *######### *****#* #
 # ************#####* #
 ###############   #@##

编辑:

  • (247-> 245)内联e并将其重命名为g
  • (245-> 249)修复出口在入口正上方的错误
  • (249-> 246)内联+简化
  • (246-> 244)遍历每个字段的更短方法

8

ANSI C(384个 373 368字符)

这是我的C尝试。编译并在Mac OS X上运行。

m[9999],*r=m,*s=m,c,R=0,*a,L;
P(){while(*s++)putchar(*(s-1));}
C(int*l){if((l-s+2)%R==0||(l-s)%R==0||l-s<R||l>r-R)*l=42,P(),exit(0);}
e(int*l){if(*l==32)C(l),*l=42,e(l-1),*l=32,*l=42,e(l-R),*l=32,*l=42,e(l+1),*l=32,*l=42,e(l+R),*l=32;}
main(){while(~(c=getchar()))*r++=c,R=!R&&c==10?r-s:R,L=c==64?r-s-1:L;L%R==0&&e(s+L+1);(L+2)%R==0&&e(s+L-1);L<R&&e(s+L+R);e(s+L-R);}

几个测试的样本输出:

####   
#  #   
@*#####
#*****#
#    *#
#####*#

###*###################
###*        #******** #
##**#########**    #* #
 #*************#####* #
 ###############   #@##

局限性:仅适用于不超过1000个字符的迷宫,但是可以很容易地增加它。我只是选择了一个任意数字,而不用理会malloc / remalloc。

另外,这是我写过的最警告的代码。19个警告,尽管XCode代码突出显示时更是如此。:D

编辑:编辑并测试了从main删除int,以使用〜代替!= EOF和putchar代替printf。感谢您的评论!


您可以使用
9999-

做得好!int 之前省略“ ” main并保存4个字符。也可以使用putchar(*(s-1))而不是printf("%c",*(s-1))保存4个以上。
Casey

您也可以替换0xA通过10!=通过^
Lowjacker 2011年

更好的是:您可以使用~操作员检查EOF:while(~(c=getchar())
Lowjacker 2011年

我也可以放下!L &&警戒来设置L,即“ @”迷宫中的位置。
乔纳森·沃特莫夫

4

Python,339个字符

import sys
M=list(sys.stdin.read())
L=len(M)
R=range(L)
N=M.index('\n')+1
D=2*L*[9e9]
D[M.index('@')+N]=0
J=(1,-1,N,-N)
for x in R:
 for i in[N+i for i in R if' '==M[i]]:D[i]=min(1+D[i+j]for j in J)
e=[i+N for i in R[:N]+R[::N]+R[N-2::N]+R[-N:]if 0<D[i+N]<9e9][0]
while D[e]:M[e-N]='*';e=[e+j for j in J if D[e+j]<D[e]][0]
print''.join(M)

生成通过迷宫的最短路径。

输出例如迷宫:

####   
#  #   
@*#####
#*    #
#******
#######

###*###################
###*        #     *** #
## *######### *****#* #
 # ************#####* #
 ###############   #@##

为什么所有的加法和减法都用N表示?
Lowjacker 2011年

它可以防止第10行中的索引D [i + j]变为负数。和d在管线12 [E + D]
基思兰德尔

1

蟒蛇- 510 421个字符

m=[]
i=raw_input
l=i()
x=y=-1
while l:
 if y<0:x+=1;y=l.find('@')
 m.append(list(l));l=i()
s=(x,y)
t={}
q=[s]
v={s:1}
while 1:
 try:(i,j),q=q[0],q[1:];c=m[i][j]
 except:continue
 if c==' 'and(i*j==0)|(i+1==len(m))|(j+1==len(m[0])):break
 for d,D in(-1,0),(0,-1),(1,0),(0,1):
  p=(i+d,j+D)
  if not p in v and'#'!=c:v[p]=0;q.append(p);t[p]=(i,j)
while(i,j)!=s:m[i][j]='*';i,j=t[(i,j)]
print'\n'.join(''.join(l)for l in m)

*在第一个测试用例(python 2.6.1)的右下角有一个。有什么想法吗?
Lowjacker 2011年

@Lowjacker谢谢,似乎在打高尔夫球时我添加了一个使它看起来像是可行的错误,但仅用于测试用例,甚至勉强:P
Juan

很好,现在可以使用。但是您忘记了print b,rprint (i,j),我认为这是为了调试:)
Lowjacker 2011年

0

Python 3,275字节

import sys
def q(g,s=[]):w=len(g[0])+1;k='@'.join(g)+w*'@';*p,x=s or[k.find('#')];return'@'>k[x]and{x}-{*p}and[p,min((q(g,s+[x+a])or k for a in(-1,1,-w,w)),key=len)]['*'>k[x]]
g=''.join(sys.stdin.read());s=q(g.split('\n'))
for i in range(len(g)):print(end=[g[i],'+'][i in s])

在线尝试!

查找ASCII道路上最短路线的答案端口。

用途'#'为起点,'*'为末,'@'墙面和' '空的空间。在这种情况下,该函数q是一个辅助函数,它返回迷宫中路径最短的一维数组。f通过不分配变量,可以将函数缩短4个字节s。这是非常低效的,并且可能会超时,因为它会为迷宫中的每个字符调用寻路函数。

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.