Eine dehnbare Schlange sieht ungefähr so aus:
<||=|||:)~
Jede separate Folge von vertikalen Balken ( |
) in einer dehnbaren Schlange, die als dehnbarer Abschnitt bezeichnet wird, kann einzeln auf das Doppelte ihrer Breite ausgedehnt werden und wird mit abwechselnden Schrägstrichen ( /
, \
) gezeichnet , sobald sie ausgedehnt sind.
Die bestimmte Schlange oben hat zwei derartig dehnbare Teile, was vier mögliche Posen ergibt:
<||=|||:)~
</\/\=|||:)~
<||=/\/\/\:)~
</\/\=/\/\/\:)~
Die allgemeine Form einer dehnbaren Schlange in ihrer am wenigsten gedehnten Haltung wird durch diesen regulären Ausdruck definiert :
<(\|+=)*\|+:\)~
Was kann in Worten ausgedrückt werden als:
<
, gefolgt von einer beliebigen Anzahl von Sequenzen von|
's, verbunden mit=
Zeichen, gefolgt von:)~
.
Also <|:)~
und <||:)~
und <|=|:)~
und <|=|=||=|||||=||:)~
sind dehnbare Schlangen, aber <=:)~
und <=|:)~
und <||=:)~
und <|==||:)~
sind es nicht.
Dehnbare Schlangen können auch nach links statt nach rechts schauen, z ~(:|||=||>
. Die Formen sind die gleichen, nur gespiegelt.
Herausforderung
Schreiben Sie ein Programm, das eine einzelne Zeile mit zwei sich gegenüberliegenden dehnbaren Schlangen mit einer gewissen Anzahl von Leerzeichen dazwischen aufnimmt. Beide Schlangen befinden sich in ihrer am wenigsten gedehnten Position (alle vertikalen Balken, keine Schrägstriche). Die Zeichenfolge beginnt mit dem Schwanz der nach rechts zeigenden Schlange und endet mit dem Schwanz der nach links zeigenden Schlange (Sie können optional davon ausgehen, dass es auch eine nachgestellte Newline gibt).
Hier ist zum Beispiel eine mögliche Eingabe mit fünf Leerzeichen zwischen den Schlangen:
<|=||:)~.....~(:||||>
Ich verwende Punkte ( .
) anstelle von Leerzeichen, um die Übersichtlichkeit zu verbessern.
Nullabstände zwischen Schlangen sind ebenfalls gültige Eingaben:
<|=||:)~~(:||||>
Wir sagen, die Schlangen küssen sich, wenn sich ihre Zungen so berühren.
Ihr Programm muss eine Kombination der dehnbaren Teile beider Schlangen so erweitern, dass die Schlangen die geringstmögliche Anzahl von Zwischenräumen zwischen sich haben (ohne sich zu überlappen), dh, dass die Schlangen dem Küssen so nahe wie möglich kommen .
Die beiden Schwänze der Schlangen sind fixiert, aber ihre Köpfe und Körper können sich bewegen - rechts für die nach rechts gerichtete Schlange, links für die nach links gerichtete Schlange - je nachdem, welche dehnbaren Teile gedehnt wurden.
Die Ausgabe Ihres Programms ist die einzeilige Zeichenfolge (plus optionaler abschließender Zeilenumbruch), die die Schlangen so nah wie möglich am Küssen zeigt, wobei abwechselnd Schrägstriche anstelle von vertikalen Balken für gestreckte Teile gezeichnet werden, die verlängert wurden.
Die Ausgabe für <|=||:)~.....~(:||||>
(von oben) wäre beispielsweise:
</\=||:)~~(:/\/\/\/\>
Dies ist die einzige Lösung, da sich bei jeder anderen Kombination der gedehnten Teile die Schlangen entweder überlappen oder weiter vom Küssen entfernt sind.
Wenn mehrere Lösungen möglich sind, kann es sich bei der Ausgabe um eine beliebige handeln.
Zum Beispiel, wenn die Eingabe wäre
<|=||:)~.....~(:|||=|>
die Ausgabe könnte sein
<|=/\/\:)~~(:/\/\/\=|>
oder
</\=||:)~~(:/\/\/\=/\>
Denken Sie daran, dass es nicht immer möglich ist, die Schlangen zum Küssen zu bringen, aber Sie müssen sie trotzdem so nah wie möglich bringen.
Zum Beispiel, wenn die Eingabe wäre
<||=||||:)~...~(:||>
die Ausgabe könnte sein
</\/\=||||:)~.~(:||>
oder
<||=||||:)~.~(:/\/\>
Wenn sich die Schlangen bereits küssen, entspricht die Ausgabe der Eingabe. z.B
<|=||:)~~(:||||>
Im Allgemeinen ist die Ausgabe dieselbe wie die Eingabe, wenn sich die Schlangen durch die Ausdehnung eines dehnbaren Abschnitts überlappen würden. z.B
<|||=|||:)~..~(:||||=|||||=||||||>
Anmerkungen
- Übernimmt wie gewohnt die Eingabe von stdin oder der Befehlszeile oder schreibt eine Funktion, die eine Zeichenfolge akzeptiert. Ausgabe drucken oder zurücksenden.
- Sie können Punkte (
.
) in der Eingabe und Ausgabe anstelle von Leerzeichen () verwenden, wenn Sie dies vorziehen.
- Es ist nur wichtig, dass sich Schrägstriche in der Reihenfolge der vertikalen Balken abwechseln, die sie ersetzt haben. Ihre Reihenfolge in der Schlange insgesamt oder ob ein vorwärts oder rückwärts gerichteter Schrägstrich zuerst kommt, spielt keine Rolle.
- Dehnbare Teile können sich nicht teilweise erstrecken - es ist genau doppelt so lang oder überhaupt nicht.
Wertung
Das ist Code-Golf . Die kürzeste Übermittlung in Bytes gewinnt. Tiebreaker ist frühere Antwort.
quelle
>
würde es auch nicht<
dasselbe für(
und werden)
), aber er sagt auch "Es ist nur wichtig, dass sich Schrägstriche in der Reihenfolge der vertikalen Balken abwechseln, die sie ersetzt haben Schlange auf freiem Fuß oder ob ein vorwärts oder rückwärts gerichteter Schrägstrich zuerst kommt, spielt keine Rolle. "Antworten:
CJam,
87717068 BytesProbieren Sie es online im CJam-Interpreter aus .
Wie es funktioniert
quelle
Retina ,
209107999792 BytesZu Zählzwecken wird jede Zeile in einer separaten Datei abgelegt. Sie können den Code jedoch mit dem
-s
Flag aus einer einzelnen Datei ausführen .Bringen Sie die besten Eigenschaften von .NET Regex und Retina zusammen: Balancing Groups, Lookbehinds mit beliebiger Länge und wiederholte Substitution von Regex.
Im Wesentlichen codiert der lange reguläre Ausdruck eine gültige Lösung und der Backtracker der regulären Ausdrucksmaschine findet eine der für mich optimalen.
Erläuterung
Lassen Sie uns zunächst überlegen, wie wir mit einer regulären Ausdrucksweise eine gültige Lösung finden können (die nicht unbedingt die richtige Ausgabe liefert). Wir können die Bilanzgruppen von .NET verwenden , um die dehnbaren Teile zu zählen. Betrachten Sie den folgenden einfacheren regulären Ausdruck:
Wir können das erkennen.
Dies entspricht der gesamten Zeichenfolge, wobei
1
für jedes Feld in der Eingabe ein Capture auf den Gruppenstapel verschoben wird. Wir werden diesen Stapel verwenden, um sicherzustellen, dass die dehnbaren Teile genau den in diesen Gruppen erfassten Raum ausfüllen.Weiter ist ein Lookbehind. Der Haken ist, dass Lookbehinds in .NET von rechts nach links abgeglichen werden (so sollten Sie sie also lesen). Dies gibt uns die Möglichkeit, die Zeichenfolge ein zweites Mal zu durchlaufen und herauszufinden, ob es eine Teilmenge von dehnbaren Teilen gibt, die sich aus der Anzahl der übereinstimmenden Leerzeichen zusammensetzt. Blick hinter die Kulissen von rechts nach links:
Dies soll nur sicherstellen, dass wir tatsächlich am Ende der Saite (dem Schwanz der Schlange) beginnen.
Für jedes dehnbare Teil entspricht dies entweder nur dem gesamten Teil, ohne etwas zu tun (
\|+
), oder es entspricht dem gesamten Teil, während das Abspringen vom Stapel erfolgt1
((?<-1>\|)*
). Diese Abwechslung stellt sicher, dass wir einen dehnbaren Teil nur vollständig ausdehnen oder unverändert lassen können und keine Dinge wie erhalten|/\|
. Dann fahren wir mit dem nächsten dehnbaren Teil fort[^|]+
.Schließlich stellen wir sicher, dass wir die gesamte Zeichenfolge (beide Schlangen) durchlaufen haben und der Stapel
1
vollständig leer ist. Das heißt, wir haben eine Teilmenge eines dehnbaren Teils gefunden, die genau der Anzahl der zuvor erfassten Räume entspricht.Der Backtracker durchläuft die Zeichenfolge und probiert alle Kombinationen unveränderter und erweiterter Teile aus, bis das Teilmengenproblem gelöst ist. Wenn eine solche Untermenge nicht existiert, schlägt der Lookbehind fehl. Dies führt dazu, dass der Backtracker zum
\S+( )+.+
Teil zurückkehrt und versucht, ein Feld weniger zu erfassen( )+
(was.+
stattdessen nur abgedeckt wird ). Aufgrund der Gier von+
versuchen wir daher, so viele Räume wie möglich zu füllen.Sie können die Gültigkeit dieses Ansatzes mit dieser leicht geänderten Substitution überprüfen:
So erhalten Sie eine Zeichenfolge
=spaces=
mit genau der Anzahl von Leerzeichen, die mit den angegebenen Schlangen gefüllt werden können.Ich musste ein paar weitere Tricks hinzufügen, um die korrekten
|
s tatsächlich zu erweitern . Grundsätzlich möchte ich alle|
s ersetzen, die mit dem(?<-1>\|)+
Zweig abgeglichen wurden . Die Idee ist, ein einzelnes Zeichen zu finden, den Löser in einen Lookaround zu versetzen und ein Flag zu setzen, wenn das Match zufällig in diesem Zweig liegt. Wenn dieses Flag nicht gesetzt war, wird die Übereinstimmung am Ende ungültig, um das Ersetzen anderer Zeichen zu vermeiden.Dazu verwenden wir eine Reihe verschachtelter Lookarounds. Auch hier werden die Lookbehinds von .NET mit variabler Länge von rechts nach links abgeglichen. Wenn wir also Lookaheads und Lookbehinds verschachteln, können wir die Regex-Engine die Zeichenfolge mehrere Male durchlaufen lassen. Aus Golfgründen wird der Löser in meiner tatsächlichen Lösung umgekehrt (beginnend am Ende, indem die Zwischenräume von rechts nach links aufgenommen und dann die Teilmengensumme von links nach rechts aufgelöst werden), aber ansonsten ist die Struktur des Lösers genau dieselbe . Lassen Sie uns den gesamten regulären Ausdruck analysieren:
Wir passen ein einzelnes Zeichen an, erfassen dann den Rest der Zeichenfolge und bewegen den Cursor an das Ende der Zeichenfolge. Wir werden diese Gruppe
1
später verwenden, um im Löser zu überprüfen, ob wir uns an der Position des Spiels befinden.Dies ist wie der erste Teil des oben beschriebenen einfachen Lösers, mit der Ausnahme, dass wir die Leerzeichen von rechts nach links aufnehmen. Das Zurückverfolgen der Anzahl der Leerzeichen funktioniert genauso wie zuvor, außer dass wir jetzt group verwenden
5
.Dies ist das Gleiche wie zuvor, mit der Ausnahme, dass wir von links nach rechts gehen und jedes Mal, wenn wir einen
|
Zweig in der expandierenden Verzweigung zuordnen, prüfen wir, ob dieser mit dem richtigen übereinstimmtDies ist ein optionaler Lookahead. Es wird erneut versucht, eine Übereinstimmung mit der Gruppe
1
herzustellen (was hier nur möglich ist, wenn wir direkt nach dem übereinstimmenden Zeichen sind). In diesem Fall wird eine leere Zeichenfolge in einer Gruppe erfasst4
, die angibt, dass wir das aktuelle Zeichen in einer gefunden haben der erweiterten Bits. Wenn\1
keine Übereinstimmung vorliegt,4
wird nichts erfasst.?
Dadurch wird sichergestellt, dass der fehlerhafte Lookahead den Solver überhaupt nicht beeinträchtigt.Schließlich überprüfen wir nach Abschluss der Lösung nur,
\4
ob dieser Lookahead verwendet wurde. In diesem Fall möchten wir das aktuelle Zeichen durch ersetzen/\
.Eine Schwierigkeit bleibt bestehen: die richtige Anzahl von Leerzeichen entfernen. Der kürzeste Weg, dies zu tun, den ich bisher gefunden habe, besteht darin, ein Leerzeichen zusammen mit dem einzufügen
/\
und dann in einem separaten Schritt ein Leerzeichen zwischen den Zungen für jedes dieser Markierungsfelder zu entfernen:quelle
Ruby
191 187 186 170162Dies ist eine Funktion, die eine Zeichenfolge als Parameter verwendet und eine Zeichenfolge zurückgibt.
Online-Tests: http://ideone.com/uhdfXt
Hier ist die lesbare Version:
In der Golfversion entspricht die
KISS
Hauptfunktion der obigen Funktion, und dieCOMBINATIONS
Funktion wurde eingezeichnet.quelle
<|=||:)~~(:||||>
, was in der Spezifikation als gültige Eingabe angegeben ist.Python, 205 Bytes
Ein einziges Lambda sieht gut aus, aber ich bin mir fast sicher, dass dies nicht der beste Weg ist. Aber ich poste das, weil alles, was ich bisher habe, halb anständig aussieht.
Dies ist eine einfache rohe Gewalt über alle möglichen Ersetzungen von
|
mit/\
, wobei die ungültigen Konfigurationen herausgefiltert werden. Die einzige saubere Bit Ich glaube , ist , dass wir tatsächlich jede nicht ersetzen|
mit/\
direkt - wir zuerst ersetzen|
mitX
und fallen.
für jeden Ersatz aus der Mitte nehmen Sie die minimale Länge Zeichenfolge über alle gültigen Strings, dann ersetzen dieX
s mit/\
.Ich habe ein paar andere Ansätze ausprobiert, darunter auch rekursive, aber sie endeten ziemlich chaotisch. Ich habe auch gelernt, dass sich
re.split
derzeit keine leeren Zeichenfolgen teilen, was bedauerlich war, da eine meiner Ideen darin bestand, an\b
Wortgrenzen zu spalten .quelle
Mathematica, 381 Bytes
Reine Funktion, die den String als Argument verwendet. Erwartet
.
eher alszwischen den Schlangen.
Ich hätte nicht gedacht, dass es so schlimm werden würde ... Hier ist, was ich hatte, bevor ich es zusammengeschlagen und alles hinzugefügt habe.
Hier ist ein Beispiel mit Erklärung:
quelle
a=StringReplace;b=StringSplit;c=StringLength;d=Total;
die folgenden Elemente an einer anderen Stelle im Inneren verwendet und ersetzt werden:a=StringReplace;b=StringSplit;c=StringLength;d=Total;a[MapAt[a[#,"|"->"/\\"]&,b[#<>"="<>#2,"="],#3]~StringRiffle~"=",")="->")~"<>If[#4>0,"."~StringRepeat~#4,""]<>"~"]&[#1,#3,Sequence@@Function[{l,s},{#,#2-d@Extract[l,#]}&[Flatten[l~Position~#~Take~#2&@@@Tally@#&@@Select[Subsets@l,d@#<=s&]~MaximalBy~d,1],s]][c/@StringCases[#1<>#3,"|"..],c@#2]]&@@#~b~"~"&
Prolog (ECLiPSe), 438 Bytes
Meine anderen Antworten lösten das falsche Problem (entschuldigen Sie das Rauschen). Hier ist ein weiterer Versuch in Prolog, der tatsächlich alle Regeln einhält.
Tests
(Format: Eingabe, Ausgabe, Zeilenumbruch)
Erklärungen
Das Hauptprädikat ist
s/2
, das die Eingabe als erstes Argument verwendet und das Ergebnis mit dem zweiten Argument (beiden Zeichenfolgen) aufhebt. Die Eingabe wird in eine Liste von Zeichencodes umgewandeltE
.Dann
s(E,Z,X,Y,L)
destructures die Liste in den folgenden Elementen:Z
Anzahl der Leerzeichen zwischen den SchlangenX
undY
abstrakte Darstellung des linken und rechten KörpersDas Format eines Körpers ist eine Liste von
n:N
oders:N
Ausdrücken, wobeiN
es sich um eine positive Länge handelt.n
Mittelnormal
unds
Mittelstretched
.L
Gesamtlänge der ListeDas Interessante daran
s/5
ist, dass es in beide Richtungen geht , dh wir können eine Schlange bauen, wenn andere Argumente instanziiert werden:Q
, der die neuen Schlangen voneinander trennt , minimiert wird . Die Gesamtlänge der berechneten Zeichenfolge ist begrenzt, sodass die Suche beendet wird.quelle
Python 2.7.3
427421400371 BytesCode ohne Golf hier -
Testen der Golflösung -
Sicherlich kann dies besser gemacht werden (ich kann nicht herausfinden, wie :)).
Lassen Sie mich wissen, wenn ich beim Golfen etwas Offensichtliches verpasst habe (Es ist mein erster Codegolf, ich mache vielleicht etwas Dummes: P)
quelle
exit
fürsys.exit()
(vergessenexit
existiert). Und Sie haben Recht,__import__
können entfernt werden, die wie 20 Zeichen beseitigt :)> 6
Zeichen ein Aliasing wert sein, wenn Sie es zweimal verwenden,> 3
Zeichen, wenn Sie es dreimal verwenden. Ich bin nicht sicher, ob derf=' '
Alias es wert ist (ich zähle zweimal)05AB1E , 93 Bytes
Viel zu lang ..>.>
Probieren Sie es online aus oder überprüfen Sie alle Testfälle oder überprüfen Sie alle möglichen Ergebnisse für alle Testfälle .
Erläuterung:
quelle