Đổ đầy mê cung với một con Rắn bám tường cho đến khi nó bị mắc kẹt


21

Làm cho một con rắn lấp đầy bất kỳ mê cung (cho đến khi nó bị mắc kẹt).

Con rắn

Con rắn bắt đầu tại một điểm bắt đầu nhất định, chỉ EAST . Nó di chuyển bằng cách luôn luôn có một bức tường hoặc một phần cơ thể của nó ngay lập tức vào TRÁI đầu (" người theo dõi quy tắc bên trái "), cho đến khi nó bị kẹt vì cả bốn hướng xung quanh đầu đều bị chiếm giữ. (Lưu ý: một con rắn bị mắc kẹt có thể không thể lấp đầy tất cả không gian có thể tiếp cận, nhưng đó không phải là mục tiêu!)

Các thách thức

Viết chương trình hoặc chức năng chấp nhận mê cung làm đầu vào dưới dạng văn bản 2D:

  • Đầu vào có thể ở bất kỳ định dạng hợp lý nào: ví dụ: danh sách các chuỗi, một chuỗi có dòng mới, tệp.
  • Mê cung có tường (" #"), khoảng trống (" ") và chính xác một điểm bắt đầu (" o").
  • Bạn có thể chọn

    • hoặc giả định rằng hàng đầu tiên và cuối cùng và cột hoàn toàn là các bức tường;
    • hoặc giả định rằng mọi đầu vào được coi là có một lớp tường bên ngoài ngầm
  • Bạn có thể giả sử rằng điểm bắt đầu có một bức tường (hoặc một bức tường ẩn) ngay phía trên nó (BẮC) và con rắn có thể thực hiện một bước di chuyển hợp lệ theo hướng EAST hoặc SOUTH.

  • Bạn có thể cho rằng không có ký tự nào khác xuất hiện trong văn bản (ngoại trừ dòng mới nếu đầu vào của bạn cần chúng).
  • Bạn có thể giả định rằng tất cả các dòng có cùng độ dài.

và in / trả về một "mê cung đầy" như đầu ra, với một ảnh chụp nhanh của con rắn tại thời điểm nó bị mắc kẹt :

  • Cơ thể của con rắn được đại diện bởi các nhân vật >v<^chỉ vào nơi phân đoạn tiếp theo của nó
  • Điểm bắt đầu của con rắn là hướng của nó khi bắt đầu (" >" trừ khi nó phải quay ngay lập tức) hoặc một onhân vật (không cần phải nhất quán)
  • Điểm cuối của con rắn là một onhân vật

Chấm điểm

Mã golf thông thường: mã ngắn nhất sẽ thắng

Thí dụ

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#
#^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<#
#################################

Hoạt hình (cho mục đích minh họa):

nhập mô tả hình ảnh ở đây

Chỉnh sửa: lưu ý rằng, khi nghi ngờ, con rắn nên "giữ tay trái" trên tường nó đã ở trên, theo các góc, không nhảy vào tường cách đó 1 khối.

nhập mô tả hình ảnh ở đây

Cảm ơn Jonathan Allan đã đưa nó lên, và Draco18s cho ảnh chụp nhanh giải thích ở trên.

Những ví dụ khác

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#
#^<<<<<<<<<<<<<#
################

Trong ví dụ GIF, khi nó nhập vào mẫu, tại sao nó không quay lại để điền vào các phần khác của khoảng trống? Chắc chắn có thể rẽ trái rồi lên rồi lại xuống rồi quay lại, nhưng con rắn đã chọn thẳng xuống. Mục tiêu là lấp đầy càng nhiều khoảng trống càng tốt với con rắn hay chỉ theo chiến lược "rẽ phải khi gặp tường và kết thúc nếu rẽ phải hai lần"?
Bạch tuộc ma thuật Urn

2
@MagicOctopusUrn Tôi không chắc tại thời điểm nào bạn thấy sự mơ hồ. Nhưng, để trả lời câu hỏi của bạn, mục tiêu không phải là lấp đầy không gian nhiều nhất có thể. Tuy nhiên, thuật toán ("người theo dõi tường") không chỉ là "rẽ phải một lần hoặc, nếu không thể, hai lần": nếu con rắn thấy mình không có bức tường bên trái, nó sẽ phải rẽ trái (giữ "trái" tay "trên tường / trên chính nó)
Nicola Sap

(xin lỗi tôi đã đọc sai thuật toán của bạn)
Nicola Sap

2
@ jonah: đúng rồi. Có một con đường xác định duy nhất và nó không tối ưu. @ giá trị mực: có. @ jonathanallan Tôi đấu tranh để thấy sự mơ hồ nhưng có thể chỉ là tôi. Phiên bản thuật toán theo tường của tôi là: giữ hướng của bạn trừ khi bạn không gặp trở ngại bên trái nữa [đánh giá trước], trong trường hợp này rẽ trái hoặc bạn chạm tường [đánh giá thứ hai] trong trường hợp này rẽ phải nếu có thể, hoặc trò chơi kết thúc.
Nicola Sap

1
Tôi đã phải mổ xẻ gif để tìm hiểu tại sao trạng thái kết thúc lại như vậy. Nó không rõ ràng từ khung hiển thị cuối cùng, mà là từ trạng thái ngay trước đó: i.stack.imgur.com/kj67V.png Tôi hy vọng điều đó sẽ giúp mọi người.
Draco18

Câu trả lời:


8

Than , 94 68 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

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

Nhét đầu vào thành một chuỗi. Điều này có thể tránh được bằng cách sử dụng một định dạng đầu vào ít thuận tiện hơn.

Pθ…θ⌕θo

In đầu vào mà không di chuyển con trỏ, sau đó in olại, để con trỏ kết thúc bên dưới nó.

≔⁰θ

Khởi tạo hướng hiện tại.

W№KV «

Lặp lại trong khi vẫn còn một không gian trống ở một số hướng.

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

Tính xem con rắn có thể rẽ trái hay không, hay bị buộc phải rẽ phải. Mã này ≦⊖θW¬⁼§KVθ ≦⊕θcũng hoạt động cho điều này cho cùng một số byte mặc dù nó được coi 0là lên thay vì đúng vì vậy phần còn lại của mã cần phải được điều chỉnh.

✳§rdluθ§>v<^θ

Xuất ra các nhân vật cơ thể thích hợp theo hướng thích hợp.

»o

Phục hồi đầu. Điều này cũng có thể được viết khi Poin ra đầu mà không di chuyển con trỏ mỗi lần đi qua vòng lặp (nhưng điều này cho phép vòng lặp được đóng hoàn toàn cho cùng một số byte).


7

Python 2 , 273 253 242 byte

-11 byte nhờ 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

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

Điều này hoạt động bằng cách tìm kiếm chuỗi 'o 'và thay thế nó bằng '[>v<^]o', nếu nó nằm trong mê cung.

Kiểm tra tương tự cũng sẽ được thực hiện trên mê cung xoay, in ra mê cung đầy khi chuỗi không còn ở đó nữa.

Chức năng t=lambda g,k=1:'\n'.join(map(j,zip(*g.split('\n')[::k])[::-k]))được sử dụng để xoay lưới


3

Thạch , 72 56 byte

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

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

Một chương trình đầy đủ lấy đầu vào là một danh sách các chuỗi và trả về một danh sách các chuỗi với con rắn cuối cùng. Lưu ý chân trang trên TIO chuyển đổi một chuỗi dòng mới được phân tách thành đầu vào mong muốn và khôi phục các dòng mới ở cuối; Điều này chỉ đơn giản là để thuận tiện.

Giải pháp phần nào lấy cảm hứng từ phương pháp được sử dụng bởi câu trả lời Python 2 của @ Rod , mặc dù cách thực hiện rất khác nhau.


3

Ruby , 126 118 byte

-8 byte được lưu bằng cách lạm dụng +=thay vì tìm kiếm thủ công osau khi định vị lại nó.

->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}

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


3

Truy vấn T-SQL 2008, 373 371 366 byte

Tôi đã có một danh sách ưu tiên, luôn luôn trượt sang trái, thẳng, phải. Tôi đã thay đổi mức độ ưu tiên đó để luôn luôn quay trở lại, trái, thẳng, phải. Độ dốc trở lại sẽ luôn bị chặn, vì vậy mức độ ưu tiên vẫn giống nhau ngoại trừ lần trượt đầu tiên. Bằng cách vặn con rắn xuống ban đầu (C = 4), nó cố gắng trượt lên khi trượt ngược. Stunt nhỏ này đã tiết kiệm cho tôi 2 byte. Bởi vì tôi không cần thêm 1 vào ~ - ~ -c% 4.

Tôi đã chèn 2 ngắt dòng để có thể đọc được

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)

Tôi đã phải thực hiện một số điều chỉnh nhỏ để thực hiện trực tuyến này, phiên bản đã đăng chạy trong studio quản lý máy chủ MS-SQL.

Nhấn Ctrl-T trước khi thực thi trong studio quản lý máy chủ MS-SQL, điều này sẽ hiển thị kết quả dưới dạng văn bản.

Dùng thử trực tuyến


2
Tôi không có ý tưởng lật làm thế nào điều này hoạt động, nhưng tôi có thể xác minh rằng nó làm. Công việc tuyệt vời
BradC

@BradC cảm ơn vì đã xác nhận và khen ngợi. Những giải pháp Sql không nhận được nhiều tình yêu trong những ngày này.
t-clausen.dk

1

Python 3 , 343 byte

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

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

-11 byte nhờ ArBo
-4 byte nhờ Jonathan Frech


Bạn có thể chơi golf initialisation của X, YFđể X=0,1,0,-1;F,*Y=*X,0nếu tôi không nhầm. Ngoài ra, import*chi phí bạn nhiều byte hơn nó tiết kiệm.
ArBo

@ArBo Ồ, tôi nghĩ rằng nó đã tiết kiệm một số lol. Cũng thật thông minh, cảm ơn!
HyperNeutrino

Tôi nghĩ bạn có thể lưu một byte với *g,=map(...). Và sys.stdin.readlines()có lẽ làm việc?
Andras Deak

1
Ngoài ra, bạn có thể có thể lưu một vài byte bằng cách giả sử đầu vào một dòng và sử dụng input().
Andras Deak

1
if C=="o"~> if"o"==C, if g[r+X[L]][c+Y[L]]==" ", elif g[r+X[F]][c+Y[F]]>" ", if g[r-X[L]][c-Y[L]]>" "Cho phù hợp.
Jonathan Frech

1

05AB1E , 54 52 byte

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

I / O cả hai dưới dạng một chuỗi nhiều dòng.

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

[                      # 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

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.