Fülle das Labyrinth mit einer der Wand folgenden Schlange, bis sie festsitzt

21

Lasse eine Schlange jedes Labyrinth füllen (bis es stecken bleibt).

Die Schlange

Die Schlange startet an einem bestimmten Startpunkt und zeigt nach Osten . Er bewegt sich durch immer eine Wand oder einen Teil seines Körpers unmittelbar an die mit LEFT seines Kopfes ( „ linke Regel Wand Folger “), bis er stecken bleibt , da alle vier Richtungen um den Kopf besetzt sind. (Hinweis: Eine feststeckende Schlange kann möglicherweise nicht den gesamten erreichbaren Raum ausfüllen, aber das ist nicht das Ziel!)

Die Herausforderung

Schreiben Sie ein Programm oder eine Funktion, die ein Labyrinth als Eingabe in Form eines 2D-Textes akzeptiert:

  • Die Eingabe kann in jedem vernünftigen Format erfolgen: z. B. eine Liste von Zeichenfolgen, eine einzelne Zeichenfolge mit Zeilenumbrüchen, eine Datei.
  • Das Labyrinth hat Wände (" #"), leere Räume (" ") und genau einen Startpunkt (" o").
  • Sie können wählen, um

    • entweder nehmen Sie an, dass die erste und letzte Reihe und Spalte vollständig Wände sind;
    • oder nehmen Sie an, dass jede Eingabe eine implizite äußere Wandschicht aufweist
  • Sie können davon ausgehen, dass sich direkt über dem Startpunkt eine Wand (oder eine implizite Wand) befindet (NORTH) und dass die Schlange eine gültige Startbewegung in Richtung OST oder SÜD ausführen kann.

  • Sie können davon ausgehen, dass der Text keine anderen Zeichen enthält (außer Zeilenumbrüche, wenn Ihre Eingabe diese benötigt).
  • Sie können davon ausgehen, dass alle Zeilen gleich lang sind.

und druckt / gibt ein "gefülltes Labyrinth" als Ausgabe zurück, mit einem Schnappschuss der Schlange in dem Moment, in dem sie stecken blieb :

  • Der Körper der Schlange wird durch die Zeichen dargestellt, >v<^die auf das nächste Segment zeigen
  • Der Startpunkt der Schlange ist entweder ihre Richtung am Start (" >", es sei denn, sie musste sich sofort umdrehen) oder ein oCharakter (keine Notwendigkeit, konsistent zu sein).
  • Der Endpunkt der Schlange ist ein oCharakter

Wertung

Üblicher Code Golf: Der kürzeste Code gewinnt

Beispiel

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

Animiert (zur Veranschaulichung):

Bildbeschreibung hier eingeben

Bearbeiten: Beachten Sie, dass die Schlange im Zweifelsfall "die linke Hand" an der Wand halten sollte, an der sie sich bereits befindet. Folgen Sie dabei den Ecken und springen Sie nicht zu einer 1 Block entfernten Wand.

Bildbeschreibung hier eingeben

Vielen Dank an Jonathan Allan, der das Thema angesprochen hat, und an Draco18s für den erklärenden Schnappschuss oben.

Andere Beispiele

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
quelle
Wenn im GIF-Beispiel das Muster eingegeben wird, warum sollte es dann nicht zurückkehren, um die anderen Teile der leeren Räume auszufüllen? Es war definitiv möglich, nach links, dann nach oben, dann nach unten und dann wieder zurück zu drehen, aber die Schlange entschied sich stattdessen für eine gerade Abwärtsbewegung. Ist das Ziel, so viele Felder wie möglich mit der Schlange zu füllen oder nur die Strategie "rechts abbiegen, wenn Sie auf eine Mauer stoßen und wenn Sie zweimal rechts abbiegen, enden" zu befolgen?
Magic Octopus Urn
2
@MagicOctopusUrn Ich bin nicht sicher, ob ich verstehe, an welchem ​​Punkt Sie die Mehrdeutigkeit sehen. Um Ihre Frage zu beantworten, ist es jedoch das Ziel, nicht so viel Raum wie möglich zu füllen. Der Algorithmus ("wall follower") ist jedoch nicht nur "einmal rechts abbiegen oder, wenn nicht möglich, zweimal": Wenn die Schlange links von einer Mauer umgeben ist, muss sie stattdessen links abbiegen ("links halten") Hand "an der Wand / auf sich selbst)
Nicola Sap
(Entschuldigung, ich habe Ihren Algorithmus falsch verstanden)
Nicola Sap
2
@ jonah: richtig. Es gibt einen einzigen deterministischen Pfad und dieser ist nicht optimal. @ value ink: ja. @ Jonathanallan Ich kämpfe um die Mehrdeutigkeit zu sehen, aber es kann nur ich sein. Meine Version des Wandfolgealgorithmus lautet: Behalte deine Richtung, es sei denn, du hast kein Hindernis mehr zu deiner Linken [zuerst gewertet]. In diesem Fall biege nach links ab oder du triffst eine Wand [zweitens gewertet]. In diesem Fall biege nach rechts ab wenn möglich, oder Spiel vorbei.
Nicola Sap
1
Ich musste das GIF zerlegen, um herauszufinden, warum der Endzustand so war, wie er war. Es ist nicht aus dem endgültig angezeigten Frame ersichtlich, sondern aus dem Zustand kurz zuvor: i.stack.imgur.com/kj67V.png Ich hoffe, das hilft den Menschen.
Draco18s

Antworten:

8

Kohle , 94 68 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

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

Schlürfen Sie die Eingabe in eine Zeichenfolge. Dies könnte durch die Verwendung eines weniger bequemen Eingabeformats vermieden werden.

Pθ…θ⌕θo

Drucken Sie die Eingabe, ohne den Cursor zu bewegen, und drucken Sie dann oerneut nach oben, sodass der Cursor darunter endet.

≔⁰θ

Initialisieren Sie die aktuelle Richtung.

W№KV «

Wiederholen Sie diesen Vorgang, solange in eine Richtung noch Platz frei ist.

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

Berechnen Sie, ob sich die Schlange nach links drehen kann oder ob sie gezwungen ist, nach rechts zu drehen. Der Code ≦⊖θW¬⁼§KVθ ≦⊕θfunktioniert auch hier für die gleiche Byteanzahl, obwohl er als aktiv und nicht 0als richtig betrachtet wird, sodass der Rest des Codes angepasst werden muss.

✳§rdluθ§>v<^θ

Geben Sie den entsprechenden Körpercharakter in die entsprechende Richtung aus.

»o

Stelle den Kopf wieder her. Dies kann auch so geschrieben werden, Podass der Kopf gedruckt wird, ohne dass der Cursor bei jedem Durchlauf durch die Schleife bewegt wird (dies ermöglicht jedoch das implizite Schließen der Schleife bei gleicher Bytezahl).

Neil
quelle
7

Python 2 , 273 253 242 Bytes

-11 Bytes dank 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

Probieren Sie es online!

Dies funktioniert, indem der String durchsucht 'o 'und durch ersetzt wird '[>v<^]o', wenn er sich im Labyrinth befindet.

Dieselbe Überprüfung wird auch für das gedrehte Labyrinth durchgeführt, wobei das gefüllte Labyrinth gedruckt wird, wenn die Zeichenfolge nicht mehr vorhanden ist.

Die Funktion t=lambda g,k=1:'\n'.join(map(j,zip(*g.split('\n')[::k])[::-k]))dient zum Drehen des Rasters

Stange
quelle
3

Jelly , 72 56 Bytes

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

Probieren Sie es online!

Ein vollständiges Programm, das die Eingabe als Liste von Zeichenfolgen aufnimmt und eine Liste von Zeichenfolgen mit der letzten Schlange zurückgibt. Beachten Sie, dass die Fußzeile in TIO eine einzelne durch Zeilenumbrüche getrennte Zeichenfolge in die gewünschte Eingabe konvertiert und die Zeilenumbrüche am Ende wiederherstellt. Dies dient lediglich der Bequemlichkeit.

Die Lösung ist etwas inspiriert von der von @ Rods Python 2-Antwort verwendeten Methode , obwohl die Implementierung sehr unterschiedlich ist.

Nick Kennedy
quelle
3

Ruby , 126 118 Bytes

-8 Bytes werden durch Missbrauch gespart, +=anstatt onach einer Neupositionierung erneut manuell zu suchen .

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

Probieren Sie es online!

Wert Tinte
quelle
3

T-SQL 2008-Abfrage, 373 371 366 Byte

Ich hatte eine Prioritätenliste, immer links, gerade, rechts. Ich habe diese Priorität geändert, um immer zurück, links, gerade, rechts zu rutschen. Das Zurückrutschen wird immer blockiert, daher bleibt die Priorität mit Ausnahme des ersten Rutschens gleich. Wenn Sie die Schlange anfangs nach unten drehen (C = 4), versucht sie, beim Zurückrutschen nach oben zu rutschen. Dieser kleine Stunt hat mir 2 Bytes gespart. Weil ich nicht 1 zu ~ - ~ -c% 4 addieren musste.

Ich habe 2 Zeilenumbrüche eingefügt, um es lesbar zu machen

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)

Ich musste einige kleinere Anpassungen vornehmen, um dies online auszuführen, die gepostete Version läuft im MS-SQL Server Management Studio.

Drücken Sie vor der Ausführung in MS-SQL Server Management Studio die Tastenkombination Strg-T. Das Ergebnis wird als Text angezeigt.

Probieren Sie es online aus

t-clausen.dk
quelle
2
Ich habe keine Ahnung, wie das funktioniert, aber ich kann überprüfen, ob es funktioniert. Toller Job!
BradC
@BradC danke für die Bestätigung und das Kompliment. SQL-Lösungen bekommen heutzutage nicht viel Liebe.
t-clausen.dk
1

Python 3 , 343 Bytes

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

Probieren Sie es online!

-11 Bytes dank ArBo
-4 Bytes dank Jonathan Frech

HyperNeutrino
quelle
Sie können die Initialisierung von Golf X,Y und Fzu , X=0,1,0,-1;F,*Y=*X,0wenn ich mich nicht irre. Außerdem import*kostet Sie das mehr Bytes als es spart.
ArBo
@ArBo Oh, ich dachte, es spart etwas lol. Auch das ist ziemlich schlau, danke!
HyperNeutrino
Ich denke, Sie können ein Byte mit retten *g,=map(...). Und funktioniert das sys.stdin.readlines()vielleicht?
Andras Deak
1
Alternativ können Sie wahrscheinlich ein paar Bytes sparen, indem Sie eine einzeilige Eingabe annehmen und verwenden 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]]>" "Entsprechend.
Jonathan Frech
1

05AB1E , 54 52 Bytes

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

I / O beide als einzelne mehrzeilige Zeichenfolge.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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

Pyth , 161 Bytes

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

Probieren Sie es online!

Port der Python 3-Lösung von HyperNeutrino . Jetzt, wo ich damit fertig bin, denke ich, dass ich stattdessen Rods Python 2-Lösung hätte portieren sollen, aber ich habe bereits viel zu viel Zeit damit verbracht.

randomdude999
quelle