Riempi il labirinto con un serpente che segue il muro fino a quando non si blocca


21

Fai riempire un labirinto da qualsiasi serpente (fino a quando non si blocca).

Il serpente

Il serpente inizia in un determinato punto di partenza, indicando EST . Si muove avendo sempre un muro o una parte del suo corpo immediatamente a SINISTRA della sua testa (" seguace del muro della regola della mano sinistra "), finché non si blocca perché tutte e quattro le direzioni intorno alla sua testa sono occupate. (Nota: un serpente bloccato non può riempire tutto lo spazio raggiungibile, ma non è questo l'obiettivo!)

La sfida

Scrivi un programma o una funzione che accetta un labirinto come input sotto forma di un testo 2D:

  • L'input può essere in qualsiasi formato ragionevole: ad esempio un elenco di stringhe, una singola stringa con newline, un file.
  • Il labirinto ha pareti (" #"), spazi vuoti (" ") ed esattamente un punto di partenza (" o").
  • Puoi scegliere di

    • supponiamo che la prima e l'ultima riga e colonna siano interamente muri;
    • o supponiamo che ogni input sia considerato avere uno strato esterno implicito di pareti
  • Si può presumere che il punto di partenza abbia un muro (o un muro implicito) direttamente sopra di esso (NORD) e che il serpente possa effettuare una mossa di partenza valida nella direzione EST o SUD.

  • Puoi presumere che non siano presenti altri caratteri nel testo (tranne le nuove righe se il tuo input ne ha bisogno).
  • Puoi presumere che tutte le linee abbiano la stessa lunghezza.

e stampa / restituisce un "labirinto pieno" come output, con un'istantanea del serpente nel momento in cui si è bloccato :

  • Il corpo del serpente è rappresentato dai personaggi che >v<^indicano dove si trova il suo segmento successivo
  • Il punto di partenza del serpente è la sua direzione all'inizio (" >" a meno che non debba girare immediatamente) o un opersonaggio (non è necessario essere coerenti)
  • Il punto finale del serpente è un opersonaggio

punteggio

Solito codice golf: vince il codice più corto

Esempio

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

Animato (a scopo illustrativo):

inserisci qui la descrizione dell'immagine

Modifica: nota che, in caso di dubbio, il serpente dovrebbe "mantenere la mano sinistra" sul muro su cui si trova già, seguendo gli angoli, senza saltare contro un muro a 1 isolato di distanza.

inserisci qui la descrizione dell'immagine

Grazie Jonathan Allan per averlo menzionato e Draco18s per l'istantanea esplicativa sopra.

Altri esempi

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

Nell'esempio GIF, quando entra nello schema perché non dovrebbe tornare indietro per riempire le altre parti degli spazi vuoti? Era sicuramente possibile girare a sinistra, poi in alto, poi a sinistra, poi in basso, poi di nuovo in giro, ma il serpente scelse invece di scendere. L'obiettivo è riempire il maggior numero possibile di spazi con il serpente o seguire solo la strategia "gira a destra quando incontri un muro e termina se gira a destra due volte"?
Magic Octopus Urn

2
@MagicOctopusUrn Non sono sicuro di capire a che punto vedi l'ambiguità. Ma, per rispondere alla tua domanda, l'obiettivo non è quello di riempire quanto più spazio possibile. Tuttavia, l'algoritmo ("seguace del muro") non è solo "gira a destra una volta o, se non è possibile, due volte": se il serpente si trova senza un muro alla sua sinistra, dovrà invece girare a sinistra (mantenendo la "sinistra mano "sul muro / su se stesso)
Nicola Sap il

(scusa se ho letto male il tuo algoritmo)
Nicola Sap,

2
@Jonah: corretto. C'è un singolo percorso deterministico e non è ottimale. @ valore inchiostro: sì. @Jonathanallan Faccio fatica a vedere l'ambiguità, ma forse sono solo io. La mia versione dell'algoritmo che segue il muro è: mantieni la tua direzione a meno che tu non abbia più un ostacolo alla tua sinistra [valutato prima], nel qual caso gira a sinistra o colpisci un muro [valutato secondo] nel qual caso gira a destra se possibile, o game over.
Nicola Sap,

1
Ho dovuto dissezionare la gif per capire perché lo stato finale fosse così. Non è evidente dal frame visualizzato finale, ma piuttosto dallo stato appena prima: i.stack.imgur.com/kj67V.png Spero che possa aiutare le persone.
Draco18s

Risposte:


8

Carbone , 94 68 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

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

Slurp l'input in una stringa. Ciò potrebbe essere evitato utilizzando un formato di input meno conveniente.

Pθ…θ⌕θo

Stampa l'input senza spostare il cursore, quindi stampa onuovamente su, in modo che il cursore finisca sotto di esso.

≔⁰θ

Inizializza la direzione corrente.

W№KV «

Ripeti finché c'è ancora spazio libero in qualche direzione.

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

Calcola se il serpente può girare a sinistra o se è costretto a girare a destra. Il codice ≦⊖θW¬⁼§KVθ ≦⊕θfunziona anche per questo per lo stesso conteggio di byte sebbene consideri 0up invece di right, quindi il resto del codice deve essere adattato.

✳§rdluθ§>v<^θ

Stampa il carattere del corpo appropriato nella direzione appropriata.

»o

Ripristina la testa. Questo può anche essere scritto come quello Poche stampa la testa senza muovere il cursore ogni passaggio invece attraverso il loop (ma ciò consente al loop di essere implicitamente chiuso per lo stesso conteggio di byte).


7

Python 2 , 273 253 242 byte

-11 byte grazie ad 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

Provalo online!

Questo funziona cercando la stringa 'o 'e sostituendola con '[>v<^]o', se è nel labirinto.

Lo stesso controllo verrà eseguito anche sul labirinto ruotato, stampando il labirinto riempito quando la stringa non è più lì.

La funzione t=lambda g,k=1:'\n'.join(map(j,zip(*g.split('\n')[::k])[::-k]))viene utilizzata per ruotare la griglia


3

Gelatina , 72 56 byte

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

Provalo online!

Un programma completo che accetta l'input come un elenco di stringhe e restituisce un elenco di stringhe con il serpente finale. Nota il piè di pagina su TIO converte una singola stringa separata da una nuova riga nell'input desiderato e ripristina le nuove righe alla fine; questo è solo per comodità.

Soluzione in qualche modo ispirata al metodo usato dalla risposta Python 2 di @ Rod , sebbene l'implementazione sia molto diversa.


3

Rubino , 126 118 byte

-8 byte salvati abusando +=invece di cercarli manualmente odopo averli riposizionati.

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

Provalo online!


3

Query T-SQL 2008, 373 371 366 byte

Avevo un elenco di priorità, sempre a sinistra, a destra, a destra. Ho cambiato quella priorità per scivolare sempre indietro, a sinistra, dritto, a destra. Lo slittamento all'indietro sarà sempre bloccato, quindi la priorità è sempre la stessa tranne la prima striscia. Abbassando inizialmente il serpente (C = 4), tenta di strisciare verso l'alto durante il backslithering. Questa piccola acrobazia mi ha salvato 2 byte. Perché non avevo bisogno di aggiungere 1 a ~ - ~ -c% 4.

Ho inserito 2 interruzioni di riga per renderlo leggibile

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)

Ho dovuto apportare alcune piccole modifiche per eseguire questo online, la versione pubblicata funziona nello studio di gestione del server MS-SQL.

Premi Ctrl-T prima di eseguirlo nello studio di gestione del server MS-SQL, questo mostrerà il risultato come testo.

Provalo online


2
Non ho idea di come funziona, ma posso verificarlo. Ottimo lavoro!
BradC,

@BradC grazie per la conferma e il complimento. Al giorno d'oggi le soluzioni Sql non hanno molto amore.
t-clausen.dk il

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

Provalo online!

-11 byte grazie ad ArBo
-4 byte grazie a Jonathan Frech


Si può golf l'inizializzazione di X, Ye Fper X=0,1,0,-1;F,*Y=*X,0se non mi sbaglio. Inoltre, import*ti costa più byte di quanti ne risparmi.
ArBo,

@ArBo Oh, pensavo stesse risparmiando un po 'di lol. Inoltre è abbastanza intelligente, grazie!
HyperNeutrino,

Penso che puoi salvare un byte con *g,=map(...). E sys.stdin.readlines()funziona forse?
Andras Deak,

1
In alternativa, è possibile probabilmente salvare alcuni byte assumendo un input a riga singola e utilizzando 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]]>" "Di conseguenza.
Jonathan Frech,

1

05AB1E , 54 52 byte

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

I / O entrambi come un'unica stringa multilinea.

Provalo online o verifica tutti i casi di test .

Spiegazione:

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

Provalo online!

Porta della soluzione Python 3 di HyperNeutrino . Ora che ho finito, sto pensando che forse avrei dovuto eseguire il porting della soluzione Python 2 di Rod, ma ho già passato troppo tempo su questo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.