Bei 2 Ganzzahleingaben, die die Größe des Feldes darstellen, x
und y
einen Pfad durch das Feld ausgeben.
Beispielausgabe für 5, 4
:
#
#
# ###
### #
Das gesamte Feld ist 5 mal 4 groß, und es gibt einen Pfad aus Hash-Markierungen, der das Feld kreuzt.
Der Pfad sollte immer in der oberen linken Ecke beginnen und nach rechts unten verlaufen. Der gesamte Pfad sollte bei jeder Ausführung des Programms zufällig ausgewählt werden. Jeder gültige Pfad sollte eine mögliche Ausgabe sein.
Die Regeln für Pfade sind:
Hergestellt aus Hashmarks
Jeder Hash ist nur mit 2 anderen Hashes verbunden (dh der Pfad schneidet sich nicht und verläuft nicht neben sich selbst)
Die Nicht-Hash-Leerzeichen können mit jedem anderen Zeichen gefüllt werden, müssen jedoch konsistent sein (dh alle Leerzeichen, alle Punkte usw.).
Beispiele:
2, 2
##
#
3, 4
##
##
#
#
5, 5
#####
#
#
#
#
6, 5
## ###
# # #
## # #
# ## #
### #
7, 9
#######
#
#### #
# # #
# # #
# # #
# ####
#
#######
Diese Art von Pfad ähnelt einem selbstvermeidenden zufälligen Spaziergang, kann jedoch im Gegensatz zu einer echten SAW nicht an sich selbst angrenzen.
Pfadkontinuität und Pfadberührung werden beide ohne Diagonalen definiert.
Antworten:
MATLAB,
316 305 300293 BytesDanke @LuisMendo für verschiedene Vorschläge und ein paar Bytes =)
Probieren Sie es online! (Ohne Gewähr: Beachten Sie, dass einige Anpassungen erforderlich waren, damit es auf Octave ausgeführt werden konnte: Erstens musste ich das
function
Schlüsselwort entfernen und die Werte fest codieren, zweitens: Die Leerzeichen werden nicht richtig gedruckt wie in Matlab. Auch das habe ich nicht getan Überprüfen Sie die Faltungsbefehle von Octave, die sich möglicherweise anders verhalten.)Beispielausgabe für Eingabe
(7,10)
(kann schon eine Weile dauern):Erläuterung
Dadurch werden nacheinander Pfade von links oben nach rechts unten mit der gewünschten 4-Konnektivität generiert. Anschließend werden mithilfe der Zurückweisungsabtastung Pfade zurückgewiesen, die gegen das Kriterium verstoßen, dass Sie keine angrenzenden Teile haben können.
Oh und wie immer:
quelle
Befunge, 344 Bytes
Probieren Sie es online!
Wie in der MATLAB-Antwort von @flawr erwähnt, kann dies einige Zeit in Anspruch nehmen, wenn die Feldgröße nicht trivial ist. Tatsächlich ist es ziemlich einfach, in eine Situation zu geraten, in der es sich nicht lohnt, auf das Ende zu warten, da Sie mit ziemlicher Wahrscheinlichkeit bis zum Ende der Zeit warten.
Um zu verstehen, warum dies geschieht, ist es hilfreich, das Programm so zu betrachten, wie es in einem der vielen "visuellen Debugger" von Befunge ausgeführt wird. Da Daten und Code in Befunge dasselbe sind, können Sie den Pfad anzeigen, wie er sich im Laufe der Zeit ändert. Hier ist zum Beispiel eine kurze Animation, die zeigt, wie ein Teil eines Laufs auf einem langsamen Pfad aussehen könnte.
Sobald der Algorithmus diese schicksalhafte Wende nach links unten an der Feldgrenze beschließt, hat er sich im Wesentlichen zu einem Leben des ziellosen Wanderns verurteilt. Von diesem Punkt an muss es jedem einzelnen möglichen Pfad in diesem eingezäunten Bereich folgen, bevor es sich zurückziehen und die Abzweigung nach rechts versuchen kann. Und die Anzahl der möglichen Pfade in diesen Fällen kann leicht astronomisch werden.
Fazit: Wenn es lange zu dauern scheint, ist es wahrscheinlich eine gute Idee, die Ausführung abzubrechen und erneut zu beginnen.
Erläuterung
Dies ist im Grunde ein rekursiver Algorithmus, der jeden möglichen Pfad durch das Feld ausprobiert und dann Schritte abwickelt, die bereits befolgt wurden, wenn es hängen bleibt. Da Befunge nicht über das Konzept von Funktionen verfügt, kommt eine rekursive Funktion nicht in Frage, aber wir können den Prozess emulieren, indem wir den Status auf dem Stapel verfolgen.
Dies funktioniert, indem der Stapel mit potenziellen Koordinaten gefüllt wird, denen wir folgen möchten. Dann ziehen wir einen Satz vom Stapel und prüfen, ob er geeignet ist (dh in Reichweite und nicht überlappend mit einem vorhandenen Pfad). Sobald wir einen guten Platz haben, schreiben wir einen
#
in das Spielfeld an diesem Ort und fügen diese Details dem Stapel hinzu, falls wir später zurückgehen müssen.Anschließend legen wir weitere vier Sätze von Koordinaten (in zufälliger Reihenfolge) auf den Stapel und geben die möglichen Pfade an, die wir von diesem neuen Ort aus nehmen können, und springen zum Anfang der Schleife zurück. Wenn keiner der möglichen Pfade durchführbar ist, gelangen wir zu dem Punkt auf dem Stapel, an dem wir die Position der ausgeschriebenen Pfade gespeichert haben.
#
Machen Sie diesen Schritt rückgängig und versuchen Sie die potenziellen Koordinaten erneut ab einem Schritt vor dem anderen.So sieht der Code mit den verschiedenen hervorgehobenen Komponenten aus:
Lesen Sie die Breite und Höhe des Feldes und drücken Sie die Startkoordinaten zusammen mit einer
0
Typmarkierung, um einen potenziellen Pfad anstelle eines Rückverfolgungsorts anzugeben.Suchen Sie nach Backtracking-Positionen (gekennzeichnet durch eine
1
Typmarkierung), die mit einem einfachenp
Befehl zurückgesetzt werden, da sie in dem genauen Format gespeichert sind, das zum Zurückschreiben eines Leerzeichens in das Spielfeld erforderlich ist.Überprüfen Sie, ob sich die Koordinaten noch im Spielfeld befinden. Wenn sie außerhalb der Reichweite liegen, lassen Sie sie vom Stapel fallen und kehren Sie zurück, um die nächsten potenziellen Koordinaten zu ermitteln.
Wenn sie sich im Bereich befinden, erhalten Sie die nächsten beiden Werte vom Stapel. Dies ist der Speicherort des vorherigen Schritts (erforderlich für den folgenden Test).
Überprüfen Sie, ob die Koordinaten mit einem vorhandenen Streckenabschnitt in Kontakt kommen. Die Position des vorherigen Schritts wird bei dieser Prüfung offensichtlich ignoriert.
Wenn alle Tests erfolgreich sind, schreiben Sie eineSchieben Sie vier potenzielle Ziele, die vom aktuellen Standort aus erreicht werden können. Die Zufallszahl bestimmt die Reihenfolge, in der sie gepusht werden, und damit die Reihenfolge, in der sie befolgt werden.
#
in das Spielfeld, und überprüfen Sie, ob wir den Zielort erreicht haben.Wenn ja, schreiben Sie den endgültigen Pfad auf und beenden Sie das Programm.
Andernfalls speichern Sie die Koordinaten mit einer
1
Typmarkierung auf dem Stapel, um sie später zurückzuverfolgen.Dies wird durch eine Zufallszahlenberechnung unterbrochen, die wir bald brauchen werden.
Gehen Sie zurück zum Anfang der Hauptschleife und verarbeiten Sie die nächsten Werte auf dem Stapel.
quelle
QBasic, 259 Bytes
Ich liebe
GOTO
s.Grundlegende Strategie: Drucken Sie bei jedem Schritt ein
#
an die aktuelle Position und bewegen Sie sich in eine zufällige Richtung. Ein Arraya
von Nullen und Einsen zeichnet auf, wo wir waren. Wenn der Umzug legal ist und uns zum Endpunkt bringt,GOTO 9
beenden Sie die Schleife und drucken Sie das Finale aus#
. Andernfalls, wenn der Umzug legal ist, machen Sie einen weiteren Schritt. Anderenfalls den Bildschirm leeren und von vorne beginnen (viel besser als das Codieren eines Backtracking-Algorithmus!).Auf meinem Laptop in QB64 getestet, führt dies in der Regel in höchstens
9, 9
fünf Sekunden zu einem Ergebnis . Läufe10, 10
haben zwischen drei und 45 Sekunden gedauert. Theoretisch haben alle legalen Pfade eine Wahrscheinlichkeit ungleich Null, aber die Wahrscheinlichkeit eines Pfades mit großen Kurven ist verschwindend gering. Ich habe gelegentlich Pfade mit ein oder zwei kleinen Kurven gesehen:Ungolfed-Version und / oder ausführliche Erklärung auf Anfrage erhältlich.
quelle
R 225 Bytes
Erläuterung:
Wir erzeugen einen regelmäßigen (Gitter-) [x * y] ungerichteten Graphen mit zufälligen Kantengewichten und finden dann den kürzesten Weg vom Anfang bis zum Ende. In dem generierten Pfad können sich jedoch Zellen befinden, die mehr als zwei Nachbarn haben, zum Beispiel:
Wir sollten also zweimal den Algorithmus mit dem kürzesten Pfad anwenden. Beim zweiten Mal setzen wir alle Wertigkeiten auf 1, mit Ausnahme derjenigen, die sich im aktuell gefundenen Pfad befinden und auf 0 gesetzt sind.
Ergebnis
Ungolfed:
quelle
JavaScript (ES7),
333331330329324318312 ByteErweiterung:
#
s werden zufällig im Array platziert, bis mit einer Breitensuche ein Pfad durch das Feld gefunden wird; der erste und daher kürzeste derartige Pfad wird dann ausgegeben; Dies garantiert, dass sich der Pfad nicht selbst schneidet. Beachten Sie, dass es insbesondere bei größeren Feldern möglich ist, den Stack der JS-Engine zu überschreiten, bevor ein Pfad gefunden wird. Ungolfed:quelle