Labirenti duvara oturan bir Snake ile doldurun


21

Bir yılanı labirentin doldurmasını sağlayın (sıkışana kadar).

Yılan

Yılan, belirli bir başlangıç ​​noktasında başlar ve EAST'ı gösterir . Her zaman bir duvar ya da hemen vücudunun bir kısmını alarak hareket SOLUNA başının ( "nin sol kural duvar takipçisi sıkıştı alır") kadar başının etrafında dört yön işgal çünkü. (Not: Sıkışmış bir yılan muhtemelen ulaşılabilir tüm alanları dolduramaz, ancak amaç bu değildir!)

Meydan okuma

2D metin biçiminde bir labirenti giriş olarak kabul eden bir program veya işlev yazın:

  • Girdi, makul herhangi bir biçimde olabilir: örn. Dizelerin listesi, yeni satırlara sahip tek bir dize, bir dosya.
  • Labirentin duvarları (" #"), boş alanları (" ") ve tam olarak bir başlangıç ​​noktası (" o") vardır.
  • Seçebilirsiniz

    • ya ilk ve son satır ve sütunun tamamen duvarlar olduğunu varsayalım;
    • veya her girişin örtülü bir dış duvar katmanına sahip olduğunu düşünün
  • Başlama noktasının doğrudan üstünde (NORTH) üstünde bir duvar (veya üstü kapalı bir duvar) olduğunu ve yılanın DOĞU veya GÜNEY yönünde geçerli bir başlangıç ​​hareketi yapabileceğini varsayabilirsiniz.

  • Metinde başka hiçbir karakter bulunmadığını varsayabilirsiniz (girişiniz için gerekirse yeni satırlar hariç).
  • Tüm çizgilerin aynı uzunlukta olduğunu varsayabilirsiniz.

ve "doldurulmuş bir labirenti" çıktı olarak yazdırır / döndürür ve sıkışan anda yılanın bir görüntüsü ile :

  • Yılanın gövdesi >v<^, bir sonraki bölümünün nerede olduğunu gösteren karakterlerle temsil edilir.
  • Yılanın başlangıç ​​noktası ya başlangıçtaki yönüdür ( >hemen dönmesi ogerekmiyorsa " ") veya bir karakter (tutarlı olması gerekmez)
  • Yılanın bitiş noktası bir okarakterdir.

puanlama

Her zamanki kod golf: en kısa kod kazanır

Örnek

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

Animasyonlu (gösterim amacıyla):

görüntü tanımını buraya girin

Düzenleme: Şüphe duyulduğunda, yılanın köşesinde takip eden, 1 blok ötedeki bir duvara atlamaması için, duvarda "sol elini" tutması gerektiğini unutmayın.

görüntü tanımını buraya girin

Getirdiğin için teşekkürler Jonathan Allan ve yukarıdaki açıklayıcı resim için Draco18s.

Diğer örnekler

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 örneğinde, desene girdiğinde neden boş alanların diğer kısımlarını doldurmak için geri dönmedi? Sola, sonra yukarı, sonra, sonra, sonra da geri dönüp gitmek kesinlikle mümkündü; Hedef, yılanla mümkün olduğu kadar fazla boşluk doldurmak mı, yoksa sadece "bir duvarla karşılaşırken sağa dön ve iki kez sağa dön" son bul "stratejisini mi takip ediyor?
Magic Octopus Urn

2
@ MagicOctopusUrn Belirsizliği hangi noktada gördüğünüzü anladığımdan emin değilim. Ancak sorunuzu yanıtlamak için amaç mümkün olduğunca fazla boşluk doldurmamaktır. Bununla birlikte, algoritma ("duvar takipçisi") sadece "bir kez sağa dönüş, ya da mümkün değilse iki kez" değildir: eğer yılan kendini solunda bir duvar olmadan bulursa, sola dönmesi gerekir (solda kalması gerekir) el "duvarda / kendi kendine)
Nicola Sap

(üzgünüm, algoritma özetini yanlış okudum)
Nicola Sap

2
@ jonah: doğru. Tek bir deterministik yol var ve bu optimal değil. @ değer mürekkebi: evet. @ jonathanallan Belirsizliği görmek için mücadele ediyorum ama bu sadece ben olabilirim. Duvara devam eden algoritmanın versiyonum şudur: Artık solunuzda bir engeliniz yoksa [önce değerlendirilir], bu durumda sola dönün veya bir duvara çarptıysanız (ikinci değerlendirildi), bu durumda sağa dönün mümkünse veya oyun bitti.
Nicola Sap,

1
Son halinin neden olduğu gibi olduğunu bulmak için gif'i kesmek zorunda kaldım. Son görüntülenen kareden değil, daha önceki durumdan açıkça belli değil: i.stack.imgur.com/kj67V.png İnsanlara yardımcı olacağını umuyorum.
Draco18,

Yanıtlar:


8

Kömür , 94 68 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

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

Girdiyi bir dizgeye sıkıştırın. Bu daha az uygun bir giriş formatı kullanılarak önlenebilir.

Pθ…θ⌕θo

İmleci hareket ettirmeden girişi yazdırın ve ardından imleç üzerine gelecek şekilde otekrar yazdırın .

≔⁰θ

Geçerli yönü sıfırla.

W№KV «

Hala bir yönde boş alan varken tekrarlayın.

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

Yılanın sola ya da sağa dönmeye zorlanıp zorlanmadığını hesaplayın. Bu kod ≦⊖θW¬⁼§KVθ ≦⊕θaynı zamanda aynı bayt sayısı için de çalışır, bununla birlikte doğru değil sayılır 0, bu nedenle kodun geri kalanının uyarlanması gerekir.

✳§rdluθ§>v<^θ

Uygun gövde karakterini uygun yönde çıktılar.

»o

Kafayı eski haline getir. Bu aynı zamanda Po, imleci hareket ettirmeden kafanın her biri döngüden geçerken basdığı şekilde yazılabilir (ancak bu, aynı bayt sayısı için döngünün kapalı olarak kapatılmasını sağlar).


7

Python 2 , 273 253 242 bayt

ArBo sayesinde -11 bayt

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

Çevrimiçi deneyin!

Bu dize arayarak ve labirentte ise onu 'o 'değiştirerek çalışır '[>v<^]o'.

Döndürülmüş labirentte de aynı kontrol yapılacak, dize artık orada olmadığı zaman dolu labirentte yazdırılacak.

İşlev t=lambda g,k=1:'\n'.join(map(j,zip(*g.split('\n')[::k])[::-k]))ızgarayı döndürmek için kullanılır


3

Jöle , 72 56 bayt

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

Çevrimiçi deneyin!

Girdiyi dizge listesi olarak alan ve son yılanla birlikte dizge listesi döndüren tam bir program. TIO'daki altbilginin tek bir yeni satır ayrılmış dizgiyi istenen girişe dönüştürdüğünü ve sonunda yeni satırları geri yüklediğini unutmayın; bu sadece kolaylık sağlamak içindir.

Çözüm, @ Rod's Python 2 cevabının kullandığı yöntemden biraz esinlenmiş olsa da, uygulama çok farklı.


3

Ruby , 126 118 bayt

-8 bayt yeniden konumlandırdıktan sonra tekrar +=elle aramak yerine kötüye kullanımdan kurtarıldı 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}

Çevrimiçi deneyin!


3

T-SQL 2008 sorgusu, 373 371 366 bayt

Öncelikli bir listem vardı, her zaman sol, düz, sağ. Bu önceliği her zaman geriye, sola, düze, sağa değiştirdim. Geri kayma her zaman engellenir, bu nedenle öncelik ilk kaygan hariç aynı kalır. Yılanı başlangıçta aşağı çevirerek (C = 4), geriye doğru çekerken yukarı kaydırmaya çalışır. Bu küçük dublör beni 2 bayt kurtardı. Çünkü 1 ila ~ - ~ -c% 4 eklememe gerek yoktu.

Okunabilir hale getirmek için 2 satır sonu ekledim

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)

Bu çevrimiçi yürütmek için bazı küçük değişiklikler yapmak zorunda kaldım, yayınlanan sürüm MS-SQL server yönetim stüdyosunda çalışıyor.

MS-SQL server yönetim stüdyosunda çalıştırmadan önce Ctrl-T tuşlarına basın, bu sonuç metin olarak gösterilecektir.

Çevrimiçi deneyin


2
Bunun nasıl çalıştığı hakkında hiçbir fikrim yok, ancak bunun yapıldığını doğrulayabilirim. Şaşırtıcı iş!
BradC

@ Brad onaylamak ve iltifat için teşekkürler. Sql çözümleri bugünlerde pek sevilmiyor.
t-clausen.dk

1

Python 3 , 343 bayt

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

Çevrimiçi deneyin!

ArBo -11 bayt
-Jonathan Frech sayesinde -4-bayt teşekkürler


Sen golf başlangıç durumuna can X, Yve Fhiç X=0,1,0,-1;F,*Y=*X,0yanılmıyorsam eğer. Ayrıca, import*kaydettiğinizden daha fazla byte maliyeti.
ArBo

@ArBo Oh, biraz lol kurtardığını sanıyordum. Ayrıca bu çok zekice, teşekkürler!
HyperNeutrino

Sanırım bir bayt kurtarabilirsin *g,=map(...). Ve sys.stdin.readlines()belki çalışır mı?
Andras Deak

1
Alternatif olarak, tek satırlık bir giriş varsayarak ve kullanarak birkaç bayttan tasarruf edebilirsiniz 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]]>" "Buna göre.
Jonathan Frech

1

05AB1E , 54 52 bayt

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

Her ikisi de tek bir çok satırlı dize olarak G / Ç.

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Açıklama:

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

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

Çevrimiçi deneyin!

HyperNeutrino'nun Limanı Python 3 çözümü . Şimdi bununla işim bittiğine göre, belki de bunun yerine Rod's Python 2 çözümünü taşımam gerekirdi diye düşünüyorum, ama bunun için çok zaman harcadım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.