Bei dieser Herausforderung geht es darum, 2D-Labyrinthe in 1D-Labyrinthe zu konvertieren.
Überblick
+-+-+-+-+-+-+ +-+-+-+-+-+-+ graph {
| | | | |A| | B| A B A -- D
+ + + + +-+-+ + + + + +-+-+ \ | C -- D
| | | | | | | | \ | D -- E
+-+-+ +-+-+ + +-+-+ +-+-+ + \ | E -- F
| | |C D E F| C---D-E---F E -- G
+-+-+-+ +-+ + +-+-+-+ +-+ + | | B -- F
| | | | G | | .---G | F -- J
+ +-+-+-+ + + + +-+-+-+ + + .' / | G -- H
| | | | |H|I |J| H I-' J G -- I
+-+-+-+-+-+-+ +-+-+-+-+-+-+ (ascii) } // (graphviz dot)
Figure 1 Figure 2 Figure 3
Für die Zwecke dieser Herausforderung ist ein traditionelles 2D-Labyrinth ein rechteckiges Labyrinth, das aus Gitterpunkten gebildet wird, an denen alle folgenden Punkte zutreffen:
- Es ist geschlossen (der äußere Rand ist durch Wände verbunden).
- Alle Gitterpunkte sind mit Wänden verbunden
- Es ist verbunden (für jeweils zwei Räume X und Y gibt es einen Pfad zwischen ihnen)
- Es ist azyklisch (es gibt keine Pfade von einem Raum X zurück zu X ohne Rückverfolgung)
Abbildung 1 zeigt ein traditionelles 2D-Labyrinth. Diese Labyrinthe haben drei Bereiche von Interesse:
- Sackgassen - Orte, von denen nur ein Pfad verfügbar ist
- Korridore - Orte, von denen aus zwei Wege zur Verfügung stehen
- Entscheidungspunkte - Orte, von denen aus drei oder vier Pfade verfügbar sind
Für jedes dieser Labyrinthe kann ein Diagramm erstellt werden, in dem die Sackgassen und Entscheidungspunkte Knoten sind und zwischen jeweils zwei Knoten, die durch einen Pfad entlang eines Korridors verbunden sind, eine Kante vorhanden ist. Abbildung 2 zeigt dasselbe Labyrinth mit diesen Knoten und Abbildung 3 das Diagramm des Labyrinths (in ASCII- und Graphviz-Punktnotation).
1D Labyrinthe
1D-Labyrinthe enthalten paarweise Warp-Punkte, die (in beiden Fällen) durch einen Buchstaben gekennzeichnet sind. Abbildung 4 zeigt ein Beispiel für ein 1D-Labyrinth. Dies ist ansonsten identisch mit einem 2D-Labyrinth mit einer Höhe von 1, wie in Abbildung 5 dargestellt. Beachten Sie insbesondere in Abbildung 5 die mit gekennzeichneten Gitterpunktpositionen +
, die sich von links nach rechts abwechseln. Im 1D-Labyrinth ist jedes andere Zeichen, das mit der äußersten linken Wand beginnt, ebenfalls ein Gitterpunkt.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| D| D E|G E F| F | G | | D| D E|G E F| F | G |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 4 Figure 5
Die Regeln zum Navigieren in diesem Labyrinth lauten wie folgt. Jede Bewegung kann entweder vorwärts ( >
) oder rückwärts ( <
) dargestellt werden. Vorwärts und Rückwärts haben hier standardmäßig die gleiche Bedeutung wie unser intuitives räumliches Bewusstsein; Vorwärts geht zur Position sofort nach rechts und rückwärts sofort nach links.
Warp-Punkte repräsentieren Orte, die die Verbundenheit mit Nachbarn asymmetrisch vertauschen. Wenn Sie von einem Nachbarn zu einem Warp-Punkt kommen, wird die Position der beiden Warp-Punkte vertauscht. Wenn Sie von einem Warp-Punkt zu einem Nachbarn kommen, werden diese nicht getauscht. Beispiel: Wenn Sie in Abbildung 6 von 1 nach hinten gehen, gelangen Sie zu 2 (da 1 der Nachbar von G ist und wir uns vom Nachbarn entfernen, werden die Punkte 2 und @ vertauscht). Wenn Sie von 2 (Warp-Punkt G) nach vorne gehen, gelangen Sie zu 3 (hier beginnen wir mit einem Warp-Punkt, es gibt also keinen Tausch). Wenn Sie von 3 nach hinten gehen, gelangen Sie ebenfalls zu @.
54 2367 89^ @1
| D| D E|G E F| F | G |
Y X
Figure 6
Abbildung 6 zeigt auch ein Beispiel für die Navigation von X nach Y unter Verwendung der Bewegungssequenz <<>><>>>>>
. Diese Züge bringen Sie 123456789^
in dieser Reihenfolge zu den jeweils markierten Punkten . Probieren Sie es einfach mit dem Code-Snippet im nächsten Abschnitt aus.
Umwandlung von 2D in 1D
In einem 1D-Labyrinth kann ein Diagramm erstellt werden, in dem jeder Knoten entweder eine Sackgasse oder ein Verzerrungspunktpaar ist und Kanten zwischen zwei beliebigen Knoten vorhanden sind, die entlang eines Korridors verbunden sind. Mit dieser Grafik können wir 1D- und 2D-Labyrinthe vergleichen.
Zum Beispiel ist das 1D-Labyrinth in Abbildung 4 das gleiche Labyrinth wie in Abbildung 1. In Abbildung 7 werden den Sackgassen Beschriftungen hinzugefügt, um zu sehen, warum. Unter Verwendung dieser Beschriftungen zum Erstellen eines Diagramms ist das Diagramm von Abbildung 7 einfach wieder Abbildung 3. Abbildung 8 zeigt einen Aufriss der Erstellung dieses Diagramms.
| D| D E|G E F| F | G |
A C B J H I
Figure 7
| D| D E|G E F| F | G |
+ + + + + + + + + + + + + + + <- lattice points
|A |C | |B J|H I| <- dead ends
|A D|C D E|G E F|B F J|H G I| <- all nodes (dead ends+warp points); i.e.:
"where each end is either a dead end
or a warp point pair"; note that each
pair of warp points is the same node.
|A-D|C-D-E|G-E-F|B-F-J|H-G-I| <- corridors; note each is a connection, since
1 2 3 4 5 6 7 8 9 "edges exist between any two nodes
connected along a corridor"
graph { graph {
A -- D // 1 <----> A -- D
C -- D // 2 <----> C -- D
D -- E // 3 <----> D -- E
G -- E // 4 <----> E -- G
E -- F // 5 <----> E -- F
B -- F // 6 <----> B -- F
F -- J // 7 <----> F -- J
H -- G // 8 <----> G -- H
G -- I // 9 <----> G -- I
} ^ }
Built from | From Figure 3
1D maze `-> isomorphic mappings
Figure 8
(Beachten Sie, dass die Beschriftungen und das Layout jedes Diagramms zur Veranschaulichung künstlich ausgewählt wurden. Im Allgemeinen handelt es sich hierbei um ein Diagrammisomorphieproblem .)
Das folgende Snippet dient zur Veranschaulichung der Mechanik des 1D-Labyrinths und der Verbindung zwischen dem 1D-Labyrinth, dem Äquivalenzdiagramm und dem 2D-Labyrinth.
Während Sie in diesem Snippet durch das 1D-Labyrinth navigieren, werden die beiden zuletzt berührten Knoten hervorgehoben. Dieselben Knoten werden im Äquivalenzdiagramm und im 2D-Labyrinth auf dieselbe Weise hervorgehoben.
Im Allgemeinen kann für jedes herkömmliche 2D-Labyrinth ein entsprechendes 1D-Labyrinth dieses Typs erstellt werden. Ein etwas komplexeres Beispiel ist Abbildung 9:
+-+-+-+-+-+-+ +-+-+-+-+-+-+ graph {
| | | | | |A| | |B| A B A -- D
+ + + + + + + + + + + + + + \ / C -- D
| | | | | | | | | | \ / D -- E
+-+-+ + +-+-+ +-+-+ + +-+-+ \ / B -- E
| | |C D E | C---D-E E -- F
+-+-+-+ +-+ + +-+-+-+ +-+ + |\ E -- I
| | | | F | | .---F \ F -- G
+ +-+-+-+ + + + +-+-+-+ + + .' / \ G -- H
| | | | |G|H |I| G H-' I H -- I
+-+-+-+-+-+-+ +-+-+-+-+-+-+ (ascii) } // (graphviz dot)
Figure 9 Figure 10 Figure 11
| D| D E |F E | F | | D| D E |F E | F |
A C I B G H
Figure 12 Figure 13
Dieses Labyrinth hat einen Knoten mit vier Pfaden (E in Abbildung 10). Abbildung 11 zeigt die Grafik. Fig. 12 ist ein äquivalentes 1D-Labyrinth; und 13 zeigt dasselbe Labyrinth mit Bezeichnungen für Sackgassen zum Vergleich mit 11.
Herausforderung
Schreiben Sie mit einem 2D-Labyrinth als Eingabe eine Funktion oder ein Programm, das das 2D-Labyrinth in ein 1D-Labyrinth mit Verzerrungspunkten umwandelt. Warp Points können jeweils einen der 52 Buchstaben verwenden.
Eingabegarantien (wenn eine dieser Garantien in der Eingabe nicht erfüllt ist, müssen Sie sich nicht damit befassen):
- Das Eingabelabyrinth ist verbunden (dh Sie können jederzeit von einem beliebigen Ort zu einem anderen wechseln).
- Das Eingabelabyrinth ist geschlossen.
- Das Eingabelabyrinth ist rechteckig.
- Alle Gitterpunkte verwenden
+
. - Alle Wände zwischen Gitterpunkten in derselben Reihe werden verwendet
|
- Alle Wände zwischen Gitterpunkten in der gleichen Spalte verwenden
-
. - Alle Räume sind Teil eines Pfades (und alle innerhalb des Labyrinths).
- Pfade sind alle Leerzeichen (dies wird immer traditionell sein, ohne Verwerfungen)
- Pfade sind genau ein Leerzeichen breit.
- Das Labyrinth besteht aus Verbindungspunkten auf einem Gitter.
- Es gibt nicht mehr als 52 Gesamtknoten (dh Sackgassen plus Entscheidungspunkte) im Diagramm des Labyrinths.
Ausgabeformat:
- Ihre Ausgabe sollte eine einzelne Linie sein, die ein 1D-Labyrinth zeigt.
- Ihre Ausgabe sollte kein führendes / nachfolgendes Leerzeichen enthalten. mit der Ausnahme, dass eine nachgestellte Zeile in Ordnung ist.
- Das erste und jedes weitere Zeichen sind Gitterpunkte.
- Alle Wände sollten auf Gitterpunkten stehen; und alle Warppunkte zwischen ihnen.
- Das Diagramm Ihres 1D-Labyrinths sollte dem Diagramm des 2D-Labyrinths entsprechen.
- Ihre 1D-Labyrinthe müssen kompakt sein. Alle Nichtgitterpunkte müssen Sackgassen (dh angrenzend an Wände) oder Verzerrungspunkte sein.
- Die einzigen Buchstaben in Ihrer Ausgabe sollten Verzerrungspunkte sein. Jeder Verzerrungspunkt tritt genau zweimal auf der Linie auf.
Beispiel:
| D| D E|G E F| F | G | <- (1,2) The single line output
+ + + + + + + + + + + + + + + <- lattice point spacing... (3)
(4,6) lattice points are all walls or spaces
(5) See Figure 8
(7) D, E, F, G appear twice; no other labels
Das ist Code-Golf. Der Gewinner ist die korrekte, lückenlose Einsendung mit den wenigsten Bytes.
Testen
Es gibt keine Testfälle für diese Herausforderung, da es für jedes nichttriviale Labyrinth eine große Anzahl korrekter Ausgaben gibt.
Ich habe jedoch einen Checker in C ++ erstellt (dieser Checker zeichnet beide Lösungen durch eine Graph-Kanonisierung auf ).
Darüber hinaus finden Sie hier einige Beispiele zur Veranschaulichung der richtigen Formatierung:
Beispiel 1
+-+-+-+-+-+-+
| | | |
+ + + + +-+-+
| | | |
+-+-+ +-+-+ +
| |
+-+-+-+ +-+ +
| | |
+ +-+-+-+ + +
| | | |
+-+-+-+-+-+-+
->
| D| D E|G E F| F | G |
Beispiel 2
+-+-+-+-+-+-+
| | | | |
+ + + + + + +
| | | | |
+-+-+ + +-+-+
| |
+-+-+-+ +-+ +
| | |
+ +-+-+-+ + +
| | | |
+-+-+-+-+-+-+
->
| D| D E |F E | F |
quelle
Antworten:
Python 2 mit Igraph ,
492369 Bytes(Die fünfte und sechste Zeile beginnen jeweils mit einem Tabulator und nicht mit vier Leerzeichen, wie StackExchange zeigt.)
g+=tuple(v.neighbors())
anstelle vong.add_edge(*v.neighbors())
g-=g.es[g.incident(v)]
anstelle von gespeichertg.delete_edges(g.incident(v))
g.d=g.degree
R
für die Anzahl der Zeilen vorhanden war, und die Berechnung wurde an den einzigen Verwendungspunkt verschoben2*(i%C)
zui%C*2
,2*(i/C)
zui/C*2
, und(C-1)*j
zuj*C-j
N='n'
<'-'
und nicht==' '
, unter der Annahme, dass nur gültige Zeichen angezeigt werden.' '
anstelle der beiden Literal-Leerzeichen in der Quelle benennen'n'
und wieder verwendenN
und==N
stattdessen<'-'
fünf weitere Bytes sparen kannEs folgt eine etwas ungelöste Version. Die Grundidee besteht darin, zunächst ein Diagramm über alle Labyrinthscheitelpunkte zu erstellen (die Punkte mit ungerader Zeile und Spalte, wenn sie mit einem Nullindex versehen sind). Wenn das folgende Zeichen ein Leerzeichen ist, gibt es eine Kante von einem Scheitelpunkt zum nächsten in derselben Zeile und nicht
|
. Wenn das entsprechende Zeichen in der folgenden Zeile ein Leerzeichen ist und nicht, gibt es eine Kante vom Scheitelpunkt bis zum darunter liegenden Scheitelpunkt-
.Nachdem wir dieses Diagramm erstellt haben, wählen wir ein beliebiges Blatt aus und folgen nacheinander benachbarten Scheitelpunkten, schreiben deren Namen auf, wenn sie kein Korridor sind, und löschen die verwendeten Kanten, bis wir stecken bleiben. Dann nehmen wir ein weiteres Blatt und fahren fort, bis alle Kanten verschwunden sind.
Sie können Ergebnisse für die fünf Beispiel-Labyrinthe sehen . (Leider
igraph
nicht verfügbar bei Try It Online; diese Ergebnisse wurden aus SageMathCloud exportiert .)quelle
Haskell -
481405387 BytesDadurch wird eine Liste der Leerzeichen im Labyrinth erstellt, die durch den Index in der Zeichenfolge nummeriert sind, und zum Suchen aller Paare benachbarter Leerzeichen verwendet. Anschließend werden die Paare zu längeren Punktfolgen zusammengefügt, die auf übereinstimmenden ersten / letzten Elementen basieren, und die Korridore werden entfernt, sodass jede Sequenz einen Raum im 1D-Labyrinth darstellt. Die Sequenzen werden dann in eine Zeichenfolge übersetzt, indem Punkte im Inneren mindestens eines Raums (die Warp-Punkte) in entsprechende Buchstaben und der Rest in Leerzeichen ersetzt werden.
Das 2D-Labyrinth wird aus STDIN gelesen und das 1D-Labyrinth wird auf STDOUT gedruckt.
Edit: Reduziert um 62 Bytes ein paar Sachen neu anordnen , und der Algorithmus ein wenig ändern, und eine andere 14 durch den Ersatz
chr
mittoEnum
wie von Laikoni.Edit 2: 13 weitere Bytes durch Vereinfachung der Logik in gespeichert
(!)
, 3 durch Verwendung des>>=
Listenmuster- Übereinstimmungszuckers und 2 durch Verwendung von Concat inu
.quelle
o(x:p)q|x==last q=[q++p]|1>0=[]
funktionieren , zB sollten sie auch funktionieren.toEnum
stattdessen funktionierenchr
, dannimport Data.Char
könnte abgeworfen werden.main=interact(\m->...)
just ersetzenf m=...
. Dies sollte ausreichen, um die Python-Antwort zu unterbieten, wenn Ihnen das etwas bedeutet.