Người giải quyết mê cung văn bản


14

Đưa ra một mê cung trên stdin và một điểm vào, viết một chương trình in một đường dẫn đến lối ra trên thiết bị xuất chuẩn. Bất kỳ đường dẫn nào cũng được chấp nhận, miễn là chương trình của bạn không tạo ra đường dẫn tầm thường (đi qua mọi điểm trong mê cung) cho mọi mê cung.

Trong đầu vào, các bức tường được đánh dấu bởi a #và điểm vào bởi a @. Bạn có thể sử dụng bất kỳ ký tự nào để vẽ mê cung và đường dẫn trong đầu ra, miễn là chúng đều khác biệt.

Bạn có thể cho rằng:

  • Các điểm vào và ra nằm ở các cạnh của đầu vào
  • Mỗi dòng của đầu vào có cùng độ dài
  • Mê cung có thể giải được và không có chu kỳ
  • Chỉ có một điểm thoát

Giải pháp ngắn nhất bằng cách đếm số ký tự (Unicode).

Ví dụ

(lưu ý rằng các đầu vào được đệm bằng khoảng trắng)

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

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

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

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

Tôi có thể thêm một ký tự cho điểm cuối không? Nó sẽ làm cho chương trình của tôi dễ dàng hơn để biết khi nào kết thúc.
Peter Olson

@Peter Of The Corn: Chắc chắn rồi. Bạn không phải sử dụng cùng một ký tự để vẽ toàn bộ đường dẫn, nó chỉ cần phân biệt với phần còn lại của đầu ra.
Lowjacker

Câu trả lời:


5

Ruby 1.9, 244 ký tự

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

Đầu ra cho hai ví dụ:

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

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

Chỉnh sửa:

  • (247 -> 245) In nghiêng e và đổi tên thành g
  • (245 -> 249) Khắc phục lỗi khi lối ra ngay phía trên lối vào
  • (249 -> 246) Nội tuyến + đơn giản hóa
  • (246 -> 244) Cách ngắn hơn để lặp lại trên mọi lĩnh vực

8

ANSI C ( 384 373 368 ký tự)

Đây là nỗ lực của tôi. Được biên dịch và chạy trên 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);}

Đầu ra mẫu cho một vài thử nghiệm:

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

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

Hạn chế: Chỉ hoạt động đối với mê cung tối đa 1000 ký tự, nhưng điều này có thể dễ dàng tăng lên. Tôi chỉ chọn một số tùy ý thay vì bận tâm đến malloc / remalloc.

Ngoài ra, đây là mã có nhiều cảnh báo nhất mà tôi từng viết. 19 cảnh báo, mặc dù có vẻ như thậm chí nhiều hơn với đánh dấu mã XCode. : D

EDITS: Đã chỉnh sửa và thử nghiệm để thả int từ main, để sử dụng ~ thay vì! = EOF và putchar thay vì printf. Cảm ơn các ý kiến!


Bạn có thể sử dụng 9999 - đó là cùng số lượng ký tự
Lowjacker

Làm tốt lắm! Bỏ qua " int " trước mainvà lưu 4 ký tự. Cũng sử dụng putchar(*(s-1))thay vìprintf("%c",*(s-1)) để tiết kiệm thêm 4.
Casey

Bạn cũng có thể thay thế 0xAbằng10!=bởi ^.
Lowjacker

Thậm chí tốt hơn: bạn có thể sử dụng ~ toán tử để kiểm tra EOF:while(~(c=getchar())
Lowjacker

Tôi cũng có thể thả người bảo vệ! L && khi đặt L, vị trí trong mê cung của '@'.
Jonathan Watmough

4

Python, 339 ký tự

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)

Tạo ra một con đường ngắn nhất xuyên qua mê cung.

Đầu ra ví dụ mê cung:

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

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

Tại sao tất cả các phép cộng và phép trừ của N?
Lowjacker

Nó ngăn việc lập chỉ mục D [i + j] trong dòng 10 không bị âm. Và D [e + j] trong dòng 12.
Keith Randall

1

Con trăn - 510 421 ký tự

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)

Tôi đang nhận được *ở góc dưới bên phải, trong trường hợp thử nghiệm đầu tiên (python 2.6.1). Có suy nghĩ gì không?
Lowjacker

@Lowjacker Cảm ơn, có vẻ như trong khi chơi golf tôi đã thêm một lỗi khiến nó trông giống như nó hoạt động, nhưng chỉ dành cho các trường hợp thử nghiệm, và thậm chí sau đó hầu như không: P
Juan

Tốt, nó hoạt động bây giờ. Nhưng bạn đã quên lấy ra print b,rvà cái print (i,j)mà tôi đoán là để gỡ lỗi :)
Lowjacker

0

Python 3 , 275 byte

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])

Hãy thử trực tuyến!

Cổng câu trả lời của tôi cho Tìm tuyến đường ngắn nhất trên đường ASCII .

Sử dụng '#'để bắt đầu, '*'kết thúc, '@'cho tường và ' 'cho không gian trống. Trong đó, hàm qlà hàm trợ giúp trả về mảng một chiều với đường đi ngắn nhất trong mê cung. Hàm fcó thể rút ngắn 4 byte bằng cách không gán biến s. Điều này cực kỳ không hiệu quả và có thể sẽ hết thời gian, vì nó gọi chức năng tìm đường cho mỗi nhân vật trong mê cung.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.