Angenommen, Sie stöbern eines Tages in Ihrer großen Kiste mit nicht verwendeten Computerkabeln und -adaptern (USB-zu-USB-Mini, VGA-zu-DVI usw.). Es gibt überall verwirrte Schnüre, die ein ziemliches Durcheinander verursachen, und Sie fragen sich, ob Sie die Dinge vereinfachen könnten, indem Sie alle Schnüre zu einer langen Litze zusammenfügen und sie dann einfach aufrollen.
Die Frage ist, ist es möglich, alle Ihre Kabel und Adapter in einer langen Reihe so zu verbinden? Es ist natürlich nicht immer möglich, zB wenn Sie nur zwei Kabel mit völlig unterschiedlichen Steckern hatten, konnten diese nicht miteinander verbunden werden. Aber wenn Sie ein drittes Kabel hätten, das an beide angeschlossen werden kann, könnten Sie alle Ihre Kabel aneinander reihen.
Es ist Ihnen egal, welche Art von Steckern sich an den Enden des Kabels befinden. Sie müssen sich nicht verbinden, um eine Schleife zu bilden. Sie möchten nur wissen, ob es möglich ist, eine reine Kordel herzustellen, und wenn ja, wie.
Herausforderung
Schreiben Sie ein Programm oder eine Funktion, die eine mehrzeilige Zeichenfolge enthält, in der jede Zeile eines der Kabel darstellt, die Sie besitzen. Ein Kabel besteht aus einem oder mehreren Strichen ( -
) mit einem Stecker an beiden Enden. Ein Plug ist immer eines der 8 Zeichen ()[]{}<>
.
Das sind also einige gültige Kabel:
>->
(--[
}-{
<-----]
(---)
Das sind aber nicht:
-->
(--
)--
[{
---
Beim Anschließen von Kabeln können nur Stecker mit genau demselben Halterungstyp miteinander verbunden werden.
Das sind also einige gültige Kabelverbindungen:
...---((---...
...---))---...
...---]]---...
...---{{---...
...---<<---...
Und diese sind ungültig:
...---()---...
...---)(---...
...---{]---...
...---{[---...
...---><---...
...--->)---...
Wenn alle Kabel im Eingang neu angeordnet und in einem langen Strang verbunden werden können, geben Sie diesen Strang in einer Zeile auf Standardausgabe aus (mit einem optionalen nachgestellten Zeilenumbruch). Wenn es mehrere Lösungen gibt, können Sie eine davon für die Ausgabe auswählen. Wenn es nicht möglich ist, einen einzelnen Strang zu erstellen, geben Sie nichts aus (oder geben Sie eine leere Zeichenfolge mit einem optionalen abschließenden Zeilenumbruch aus).
Zum Beispiel, wenn die Eingabe ist
[-->
{---]
>----{
die Ausgabe könnte sein
[-->>----{{---]
wo alle Schnüre aneinandergereiht sind.
Allerdings wenn die Eingabe wäre
[-->
{---]
Die Kabel können nicht angeschlossen werden, sodass keine Ausgabe erfolgt.
Beachten Sie, dass die Kabel so oft umgedreht werden können, bis die Verbindungen hergestellt sind. ZB [-->
und <--]
sind effektiv das gleiche Kabel, weil sie die gleiche Art von Verbindungen herstellen können. Einige Ausgänge hängen möglicherweise vom Umdrehen der Eingangskabel ab.
Beispielsweise
(-[
}--]
hätte ausgeben können
(-[[--{
wo die zweite Schnur umgedreht ist, oder
}--]]-)
wo die erste Schnur umgedreht wird.
(Beachten Sie, dass im Allgemeinen das Spiegeln der gesamten Ausgabe gültig ist, da es das gleiche ist, als würde jedes Kabel einzeln gespiegelt.)
Die Länge der Kabel im Ausgang sollte natürlich mit der Länge der entsprechenden Eingangskabel übereinstimmen. Die Schnüre können jedoch so oft nachbestellt und gewendet werden, wie Sie möchten, um die reine Schnur zu erhalten. Der Eingang enthält immer mindestens ein Kabel.
Der kürzeste Code in Bytes gewinnt.
Testfälle
Fälle mit Ausgabe:
[-->
{---]
>----{
gives
[-->>----{{---]
or
[---}}----<<--]
(-[
}--]
gives
(-[[--{
or
}--]]-)
(-)
gives
(-)
[--{
gives
[--{
or
}--]
[-]
]-[
gives
[-]]-[
or
]-[[-]
[----->
)------------[
{--<
}---)
could give
[----->>--}}---))------------[
or
>--}}---))------------[[----->
or
}---))------------[[----->>--}
or
{--<<-----]]------------((---{
etc.
>-->
>->
>--->
could give
>-->>->>--->
or
>--->>-->>->
or
>->>-->>--->
or
<--<<---<<-<
etc.
(-]
]->
>-}
}-)
)-[
[-<
<-{
{-(
could give
(-]]->>-}}-))-[[-<<-{{-(
or
{-((-]]->>-}}-))-[[-<<-{
or
<-{{-((-]]->>-}}-))-[[->
etc.
Fälle ohne Ausgabe:
[-->
{---]
[-]
[-]
(-]
]->
}-)
>->
>-->
]---]
[-------------------]
]-------------------[
[-----------------]
[-----------------]
{--[
]--}
Antworten:
Nicht lesbar , 3924 Bytes
Dies ist das erste Mal, dass ich eine Call-Stack-ähnliche Struktur in Unreadable implementiert habe.
(Die erste Version davon war über 5300 Bytes, nur um eine Vorstellung davon zu geben, wie sehr ich das gespielt habe.)
Erläuterung
Betrachten Sie diese Beispieleingabe:
Während des größten Teils der Ausführung ist das Band wie folgt angeordnet:
Die Zellen 0 bis 5 sind Speicherorte für verschiedene Variablen.
Ab Zelle 6 finden Sie alle Informationen zum Kabelsatz in Ihrer Box:
Die verbleibenden Zellen nach dem „Nullterminator“ enthalten den Stapel. Jeder "Stackframe" ist eine einzelne Zelle, die auf die erste Zelle eines Kabels zeigt (die "Start Plug" -Zelle). Wenn das Programm im obigen Beispiel feststellt, dass es eine Lösung gefunden hat, enthält der Stapel 6 (
>--{
das erste Kabel) und 21 ({---]
den Spiegel des zweiten Kabels).Das Programm besteht aus drei Hauptschritten:
Die erste Stufe (Eingabe lesen und Kabelstruktur erzeugen) verwendet nur die Zellen 1 (die ich aufrufen werde
p
) und 2 (die ich aufrufen werdech
) und arbeitet in einer while-Schleife wie folgt:While-Bedingung: Inkrementiere
p
um 6, lies das nächste Zeichen (Start-Plug) in die Zelle*p
und überprüfe, ob es nicht-1
(EOF) ist.Lesen Sie nachfolgende Zeichen ein
*(p+2)
und zählen Sie sie ein*(p+1)
, bis wir auf etwas anderes als-
(Bindestrich) stoßen . An dieser Stelle*(p+1)
wird die Anzahl der Bindestriche (Kabellänge) und*(p+2)
das letzte Nicht-Bindestrichen-Zeichen (der Endstopfen) enthalten. (Wir kopieren auch die Bindestriche in Zelle 5, damit wir später in der Ausgabestufe auf diesen ASCII-Code zugreifen können.)Suchen Sie in einer while-Schleife den Spiegelstecker und speichern Sie ihn bei und erhöhen Sie ihn
*(p+3)
dannp
um 2, bis er*p
Null ist. Die Schleife sieht im Pseudocode so aus:Diese Schleife führt immer zwei Iterationen durch (den Start-Stecker und den End-Stecker) und speichert die Ergebnisse in der vierten und sechsten Zelle dieses Kabels. Wenn Sie jetzt genau hinschauen, stellen Sie fest, dass die sechste Zelle tatsächlich die richtige Position für den gespiegelten Endstecker ist, der gespiegelte Startstecker sich jedoch in der Zelle befindet, die mit „Boolean“ (Boolescher Wert für Originalkabel) beschriftet ist. Dies ist in Ordnung, da diese Zelle nur ein Wert ungleich Null sein muss.
Da
p
gerade 4 inkrementiert wurden, zeigt es jetzt auf die Zelle mit der Bezeichnung „Boolesches Anzeigekabel wird verwendet“. Auf*(p+3)
den Wert von setzen*(p-1)
. Dies bringt den gespiegelten Startstecker an die richtige Stelle.Lesen (und verwerfen) Sie ein weiteres Zeichen (was wir als Zeilenumbruch erwarten, aber das Programm prüft dies nicht).
p
Beginnt anfangs bei 0, wird jedoch im while-Zustand um 6 erhöht, sodass die Kabeldaten bei Zelle 6 beginnen.p
wird innerhalb des Schleifenkörpers um 4 erhöht, und somit insgesamt 10 für jedes Kabel, was genau das ist, was wir brauchen.Während der zweiten Stufe, Zellen # 0-4 werden von Variablen belegt , dass ich nennen werde
a
,p
,q
,m
, undnotdone
. (Zelle 5 speichert weiterhin den ASCII-Code des Bindestrichs.)Um sich auf Stufe 2 vorzubereiten, müssen wir den Wert
*p
auf 0 zurücksetzen (die Zelle mit der Bezeichnung „Nullterminator“), damit sie als Terminator für die Liste der Kabel fungieren kann. wir setzenq
(das ist unser Stapelzeiger) auch aufp+1
(dh die Zelle nach dem „Nullterminator“; hier beginnt der Stapel);*q
zu 1 (der erste Gegenstand auf dem Stapel; warum 1 später auftaucht); undnotdone
zu 1. All dies geschieht in einer einzigen Anweisung:Die zweite Stufe ist ebenfalls eine while-Schleife. Sein Zustand ist einfach
notdone
. In jeder Iteration dieser while-Schleife kann eines der folgenden vier Dinge passieren:*q
zu einem anderen geeigneten Kabel übergehen (das wir zusammen mit seinem Zwilling umgehend als "in Verwendung" markieren) und es dann erneut verwenden (dh einen neuen Stackframe erstellen).*q
da kein weiteres berechtigtes Kabel vorhanden ist. Daher müssen wir zurückverfolgen (einen Stackframe entfernen und das vorherige Kabel und seinen Zwilling als nicht mehr "in Verwendung" markieren).*q
da kein weiteres Kabel verfügbar ist, und wir können nicht zurückverfolgen, weil wir den Boden des Stapels erreicht haben. Das heißt, es gibt keine Lösung.Der Schleifenkörper prüft jede dieser vier Bedingungen in dieser Reihenfolge. Hier sind die Details:
Stellen Sie
m
undp
auf 1 und in einer while-Schleife inkrementieren Siep
um 5 (und durchlaufen Sie so die Kabel) und überprüfen Sie, ob*(p+4)
(„in use“) eingestellt ist. Ist dies nichtm
der Fall , setzen Sie den Wert auf 0.m
Teilen Sie uns am Ende dieser Schleife mit, ob alle Kabel belegt sind. In diesem Fall setzen Sienotdone
den Wert auf 0, um die Hauptschleife zu beenden. Fahren Sie andernfalls mit Schritt 2 fort.Stellen Sie
p
auf*q
(das Kabel oben im Stapel) und erhöhen Sie in einer While-Schleife, die der obigen ähnelt, den Wertp
um 5, um die Kabel zu durchlaufen. Ab wird*q
sichergestellt, dass nur diejenigen berücksichtigt werden, die wir zuvor noch nicht berücksichtigt haben. Denken Sie jedoch daran, dass der Anfangswert für einen neuen Stackframe 1 ist. Das erste Kabel ist also das in Zelle 6, bei dem es sich in der Tat um das erste Kabel handelt.Wir müssen für jedes Kabel überprüfen
*(p+4)
, ob es nicht bereits verwendet wird und ob es entweder*(q-1)
Null ist (dh, wir befinden uns am unteren Ende des Stapels, sodass der Startstecker nicht eingeschränkt ist) oder*p
(der Start des Kabels) Stecker) ist gleich*(*(q-1)+2)
(der Endstecker des Kabels direkt unter dem Stapel). Wir überprüfen die Gleichheit, indem wir in einer while-Schleifea
auf*(*(q-1)+2)
undm
auf setzen*p+1
und dann beide dekrementieren. Das+1
ist, weilm
es innerhalb der while-Bedingung dekrementiert wird, also wird es noch einmal dekrementiert alsa
. Wenna
am Ende Null ist, sind die beiden Stecker gleich.Wenn also entweder
*(q-1)
Null war oder der Gleichheitsvergleich erfolgreich war, ist das Kabel zulässig. Stellen Sie dies ein*q
,p
um das Kabel oben im Stapel durch das neue zu ersetzen. Stellen Siem
denselben Wert ein, um anzuzeigen, dass wir ein passendes Kabel gefunden haben. und dann dekrementierenp
. Diese Dekrementierung ist ein kleiner Trick, um die while-Schleife (die durch die Kabel iteriert) vorzeitig zu beenden. Der Wertp
wird erneut um 5 erhöht , sodass er in die Zelle mit dem Flag „In Use“ dieses Kabels übertragen wird. Wir wissen, dass dies Null ist, weil wir das gerade überprüft haben. Schließlich überprüfen wir nach der Kabeliterations-While-Schleife, ob der Wertm
ungleich Null ist. In diesem Fall haben wir ein passendes Kabel gefunden undp
zeigen auf die Markierung „in use“ für dieses passende Kabel. Setzen Sie ihn auf 1, um ihn als verwendet zu markieren. Auch eingestellt*(*(p-1) ? p+5 : p-5)
bis 1, um seinen Zwilling als belegt zu markieren. Inkrementieren Sieq
und setzen Sie das Neue*q
auf 1, um einen neuen Stackframe zu erstellen.Wenn wir nach der kabeliterierenden while-Schleife feststellen
m
, dass sie Null ist, gibt es keine passenden Kabel mehr, sodass wir zurückverfolgen müssen. Verringernq
Sie den Wert, um den Stapel nach unten zu verschieben, und prüfen Sie, ob er immer noch auf ein Kabel zeigt (ein Wert ungleich Null). Wenn ja, kennzeichnen Sie das Kabel und seinen Zwilling als nicht mehr verwendet. (Wir speichern den Wert von*q
inp
, um diesen Ausdruck im Code zu verkürzen.)Wenn
q
wir nach dem Dekrementieren feststellen, dass es auf einen Nullwert zeigt, dann ist dies der „Nullterminator“, was bedeutet, dass wir den Stapel unterschritten haben. Wir kommen zu dem Schluss, dass es keine Lösung gibt. Wir setzennotdone
auf 0, um die Hauptschleife zu beenden.Die dritte Stufe ist die Ausgangsstufe. Es gibt zwei Dinge, die passieren können:
Wenn es keine Lösung gibt,
p
ist sie günstigerweise Null, da wir sie auf den Wert von setzen,*q
bevor wir sie auf Null prüfen. und wenn es war eine Lösung,p
ist auf dem „Null - Terminator“ , weil es nur durch die Kabel durchlaufen, so dass wir jetzt nutzen können ,p
um Iterierte durch den Stapel. Durchlaufen Sie den Stapel, und geben Sie für jedes Kabel den Start-Plug (*(*p)
), die Bindestriche (durch Dekrementieren*(*p+1)
in einer while-Schleife) und den in Zelle 5 gespeicherten Bindestrichen-ASCII-Code sowie den End-Plug (*(*p+2)
) aus. Es ist egal, dass dadurch die Kabellängeninformationen zerstört werden. das brauchen wir nicht mehr.quelle
CJam, 67
Probieren Sie es online aus
Hinweis: Der Link verwendet den neuesten Code aus dem Repository (gepusht, aber noch nicht veröffentlicht), da er eine Fehlerbehebung enthält.
Erläuterung:
Das Programm versucht einfach alle Permutationen und alle Ausrichtungen der Schnüre.
quelle
(-] ]-> >-} }-) )-[ [-< <-{ {-(
.JavaScript (ES6), 206
Rekursive Funktion
Mehr lesbar
Prüfung
quelle
Javascript, 800 Bytes
Weit entfernt von einer optimierten Lösung, aber hier ist ein kurzer gemeinsamer Hack in Javascript (kein schickes Ecma5 oder so, weil ich es nicht kenne).
Ungolfed, hier ist es ... Ich bin sicher, dass mindestens 2 for-Schleifen hier unnötig sind und dass das Überprüfen auf einen einzelnen Elementeingang oben und eine einzelne Elementübereinstimmung unten stankig ist ... aber es scheint zu funktionieren und verarbeitet die Testeingaben.
quelle
s.charAt(x)
===s[x]
Python 3, 217 Bytes
( Demo auf Ideone )
quelle
(-] ]-> >-} }-) )-[ [-< <-{ {-(
?Lua, 477 Bytes
Akzeptiert Cords als Befehlszeilenargumente
quelle
Python 3.5,
448432427424286311 Bytes:( +25, da es einen Fehler gab, bei dem die Ausgabe länger sein kann als für einige Eingaben )
Funktioniert perfekt!
mit Ausnahme von Eingaben mit 7 oder mehr Werten. Für diese dauert es sehr lange , am wahrscheinlichsten, weil alle diese Permutationen der Eingabe plus der umgekehrten Eingabe durchlaufen werden müssen . Ich werde versuchen, dies zu beheben, wenn und wann ich kann, aber im Moment scheint dies gut genug zu sein.Alles ist gut jetzt! Wenn ich diesen Block nur irgendwie für dastry-except
Listenverständnis verwenden könnte, könnte er etwas kürzer sein und viel besser aussehen . Trotzdem funktioniert es jetzt für alle Testfälle und am besten ohne Importe! :)Probieren Sie es online! (Ideone) (284 Byte hier)
(Tipp: Um es zu versuchen, wählen Sie einfach "fork" und geben Sie dann Ihre Auswahl ein, durch Leerzeichen getrennt , und wählen Sie "run".)
Erläuterung
Grundsätzlich ist was passiert ...
B
Aus der Eingabe wird eine Liste erstellt, indem sie am Leerzeichen in ihre Komponente "cords" aufgeteilt wird.M
ist eine Zeichenfolge, die ich erstellt habe und die bei der Auswertung eine Liste zurückgibt,B
die alle Kabel enthält, diesmal jedoch rückwärts .M
wird schließlich mit sichB
selbst verkettet , um eine Listef
mit allen möglichen Ausrichtungen der "Schnüre" zu erstellen .d
erstellt, die mit dem ersten Wert (valuef[0]
) von initialisiert wirdf
.d
durchlaufen, und das letzte Zeichen jedes Werts wird mit dem ersten Zeichen jedes Elements in verglichen.f
Wenn eine Übereinstimmung gefunden wird, wird dieses Zeichen entfernt und aus der Liste zurückgegebenf
. Dies geschieht so lange, bis aIndexError
ausgelöst wird oder die Länge der Listed
überschritten wirdB
und aNameError
nach dem Aufruf von ausgelöst wird.E
Beide werden verarbeitet, und dann wirdd
der Inhalt der Liste zu einer Zeichenfolge zusammengefügt und zurückgegeben, solange die Länge der Listed
größer ist als oder gleich der Länge der ListeB
. Andernfalls wird eine leere Zeichenfolge zurückgegeben (''
), da eined
Abweichung von der angegebenen LängeB
bedeutet, dass alle "Kabel" in der Liste aufgeführt sindB
kann nicht zu einer langen "Schnur" verbunden werden.quelle
<!-- language: lang-python -->
Nach allem, was ich sehen kann, haben Sie gerade hinzugefügt. Was ändert sich daran?