Isi labirin dengan ular yang mengikuti dinding sampai macet

21

Buat ular mengisi labirin apa saja (sampai macet).

Ular

Ular mulai pada titik awal yang diberikan, menunjuk EAST . Bergerak dengan selalu memiliki dinding atau bagian dari tubuhnya segera ke KIRI kepalanya (" pengikut aturan dinding kiri "), sampai macet karena keempat arah di sekitar kepalanya ditempati. (Catatan: ular yang macet mungkin tidak dapat mengisi semua ruang yang bisa dijangkau, tapi itu bukan tujuannya!)

Tantangan

Tulis program atau fungsi yang menerima labirin sebagai input dalam bentuk teks 2D:

  • Input dapat dalam format apa pun yang masuk akal: misalnya daftar string, string tunggal dengan baris baru, file.
  • Labirin memiliki dinding (" #"), ruang kosong (" ") dan tepat satu titik awal (" o").
  • Anda dapat memilih untuk

    • bisa berasumsi bahwa baris dan kolom pertama dan terakhir seluruhnya adalah tembok;
    • atau berasumsi bahwa setiap input dianggap memiliki lapisan luar dinding implisit
  • Anda dapat mengasumsikan bahwa titik awal memiliki dinding (atau dinding implisit) langsung di atasnya (UTARA) dan bahwa ular dapat membuat langkah awal yang valid dalam arah TIMUR atau SELATAN.

  • Anda dapat mengasumsikan bahwa tidak ada karakter lain yang ada dalam teks (kecuali baris baru jika input Anda membutuhkannya).
  • Anda dapat mengasumsikan bahwa semua garis memiliki panjang yang sama.

dan mencetak / mengembalikan "labirin terisi" sebagai output, dengan snapshot ular saat macet :

  • Tubuh ular diwakili oleh karakter yang >v<^menunjukkan di mana segmen berikutnya
  • Titik awal ular adalah arahnya di awal (" >" kecuali jika harus segera berbalik) atau okarakter (tidak perlu konsisten)
  • Titik akhir dari ular adalah sebuah okarakter

Mencetak gol

Golf kode biasa: kode terpendek menang

Contoh

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

Animasi (untuk tujuan ilustrasi):

masukkan deskripsi gambar di sini

Sunting: perhatikan bahwa, jika ragu, ular itu harus "menjaga tangan kirinya" di dinding yang sudah ada, mengikuti sudut, tidak melompat ke dinding 1-blok jauhnya.

masukkan deskripsi gambar di sini

Terima kasih Jonathan Allan untuk membawanya, dan Draco18 untuk snapshot penjelasan di atas.

Contoh lainnya

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#
#^<<<<<<<<<<<<<#
################
Nicola Sap
sumber
Dalam contoh GIF, ketika memasuki pola mengapa tidak kembali untuk mengisi bagian lain dari ruang kosong? Itu benar-benar mungkin untuk belok kiri lalu ke atas lalu ke kiri lalu ke bawah lalu kembali ke sekitar, tetapi ular memilih lurus ke bawah sebagai gantinya. Apakah tujuannya untuk mengisi ruang sebanyak mungkin dengan ular atau hanya mengikuti strategi "belok kanan saat berhadapan dengan dinding dan akhiri jika belok kanan dua kali"?
Magic Gurita Guci
2
@ MagicOctopusUrn Saya tidak yakin saya mengerti pada titik apa Anda melihat ambiguitas. Tapi, untuk menjawab pertanyaan Anda, tujuannya bukan untuk mengisi ruang sebanyak mungkin. Namun, algoritme ("pengikut dinding") bukan hanya "belok kanan sekali atau, jika tidak mungkin, dua kali": jika ular menemukan dirinya sendiri tanpa dinding di sebelah kirinya, ia harus berbelok ke kiri sebagai gantinya (menjaga "kiri" tangan "di dinding / pada dirinya sendiri)
Nicola Sap
(maaf saya salah membaca ringkasan algoritme Anda)
Nicola Sap
2
@ Jonya: benar. Ada jalur deterministik tunggal dan itu tidak optimal. @ nilai tinta: ya. @ jonathanallan Saya berjuang untuk melihat ambiguitas tetapi mungkin hanya saya. Versi saya dari algoritma berikut-dinding adalah: pertahankan arah Anda kecuali Anda tidak memiliki penghalang ke kiri lagi [dievaluasi terlebih dahulu], dalam hal ini belok kiri, atau Anda menabrak dinding [dievaluasi kedua] dalam hal belok kanan jika memungkinkan, atau game over.
Nicola Sap
1
Saya harus membedah gif untuk mencari tahu mengapa kondisi akhirnya seperti itu. Ini tidak terlihat dari frame terakhir yang ditampilkan, melainkan dari negara sebelum: i.stack.imgur.com/kj67V.png Saya harap ini membantu orang.
Draco18s

Jawaban:

8

Arang , 94 68 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

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

Masukkan input ke dalam string. Ini bisa dihindari dengan menggunakan format input yang kurang nyaman.

Pθ…θ⌕θo

Cetak input tanpa menggerakkan kursor, lalu cetak olagi, sehingga kursor berakhir di bawahnya.

≔⁰θ

Inisialisasi arah saat ini.

W№KV «

Ulangi sementara masih ada ruang kosong di beberapa arah.

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

Hitung apakah ular dapat berbelok ke kiri, atau apakah terpaksa berbelok ke kanan. Kode ini ≦⊖θW¬⁼§KVθ ≦⊕θjuga berfungsi untuk ini untuk jumlah byte yang sama meskipun dianggap 0sebagai alih-alih benar sehingga sisa kode perlu disesuaikan.

✳§rdluθ§>v<^θ

Keluarkan karakter tubuh yang sesuai ke arah yang sesuai.

»o

Kembalikan kepala. Ini juga dapat ditulis sebagai Poyang mencetak kepala tanpa menggerakkan kursor setiap melewati loop sebagai gantinya (tetapi ini memungkinkan loop untuk secara implisit ditutup untuk jumlah byte yang sama).

Neil
sumber
7

Python 2 , 273 253 242 byte

-11 byte terima kasih kepada 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

Cobalah online!

Ini bekerja dengan mencari string 'o ', dan menggantinya dengan '[>v<^]o', jika ada di labirin.

Pemeriksaan yang sama juga akan dilakukan pada labirin yang diputar, mencetak labirin yang terisi ketika string tidak ada lagi.

Fungsi t=lambda g,k=1:'\n'.join(map(j,zip(*g.split('\n')[::k])[::-k]))ini digunakan untuk memutar grid

tongkat
sumber
3

Jelly , 72 56 byte

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

Cobalah online!

Program lengkap yang mengambil input sebagai daftar string dan mengembalikan daftar string dengan ular terakhir. Catatan footer pada TIO mengubah string yang dipisahkan baris baru tunggal ke input yang diinginkan dan mengembalikan baris baru di akhir; ini hanya untuk kenyamanan.

Solusi agak diilhami oleh metode yang digunakan oleh @ Rod's Python 2 jawaban , meskipun implementasi sangat berbeda.

Nick Kennedy
sumber
3

Ruby , 126 118 byte

-8 byte disimpan dengan menyalahgunakan +=alih-alih mencari secara manual olagi setelah memposisikan ulang.

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

Cobalah online!

Nilai Tinta
sumber
3

Permintaan T-SQL 2008, 373 371 366 byte

Saya memiliki daftar prioritas, selalu meluncur ke kiri, lurus, kanan. Saya mengubah prioritas itu untuk selalu meluncur ke belakang, kiri, lurus, kanan. Slithering back akan selalu diblokir, jadi prioritasnya tetap sama kecuali slither pertama. Dengan membalikkan ular pada awalnya (C = 4), ia mencoba merayap naik saat backslithering. Aksi kecil ini menyelamatkan saya 2 byte. Karena saya tidak perlu menambahkan 1 ke ~ - ~ -c% 4.

Saya memasukkan 2 jeda baris agar bisa dibaca

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)

Saya harus membuat beberapa penyesuaian kecil untuk menjalankan ini secara online, versi yang diposting berjalan di studio manajemen server MS-SQL.

Tekan Ctrl-T sebelum dijalankan di studio manajemen server MS-SQL, ini akan menampilkan hasil sebagai teks.

Cobalah online

t-clausen.dk
sumber
2
Saya tidak tahu bagaimana cara kerjanya, tetapi saya bisa memverifikasi itu. Pekerjaan luar biasa!
BradC
@BradC terima kasih atas konfirmasi dan pujiannya. Solusi sql tidak mendapatkan banyak cinta hari ini.
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))

Cobalah online!

-11 byte terima kasih kepada ArBo
-4 byte terima kasih kepada Jonathan Frech

HyperNeutrino
sumber
Anda dapat golf inisialisasi dari X, Ydan Funtuk X=0,1,0,-1;F,*Y=*X,0jika saya tidak salah. Juga, import*biaya byte Anda lebih banyak daripada menghemat.
ArBo
@ ArBo Oh, saya pikir itu menyimpan beberapa lol. Itu juga cukup pintar, terima kasih!
HyperNeutrino
Saya pikir Anda dapat menyimpan byte dengan *g,=map(...). Dan apakah sys.stdin.readlines()mungkin berhasil?
Andras Deak
1
Atau, Anda mungkin dapat menyimpan beberapa byte dengan mengasumsikan input satu baris dan menggunakan 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]]>" "Sesuai.
Jonathan Frech
1

05AB1E , 54 52 byte

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

I / O keduanya sebagai string multi-line tunggal.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

[                      # 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
Kevin Cruijssen
sumber
0

Pyth , 161 byte

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

Cobalah online!

Port solusi HyperNeutrino Python 3 . Sekarang saya sudah selesai dengan itu, saya berpikir mungkin saya seharusnya mem-porting solusi Rod's Python 2 sebagai gantinya, tapi saya sudah menghabiskan terlalu banyak waktu untuk ini.

randomdude999
sumber