Ich möchte eine neue Art von Regex-Golf-Herausforderung ausprobieren, bei der Sie aufgefordert werden, nicht-triviale Rechenaufgaben nur durch Regex-Substitution zu lösen. Um dies zu ermöglichen und weniger lästig zu sein, können Sie mehrere Substitutionen nacheinander anwenden.
Die Herausforderung
Wir fangen einfach an: Wenn eine Zeichenfolge mit zwei positiven Ganzzahlen als durch ein getrennte Dezimalzahlen angegeben wird ,
, wird eine Zeichenfolge mit ihrer Summe erstellt, auch als Dezimalzahl. Also sehr einfach
47,987
sollte sich verwandeln in
1034
Ihre Antwort sollte für beliebige positive ganze Zahlen funktionieren.
Das Format
Jede Antwort sollte eine Folge von Substitutionsschritten sein, wobei jeder Schritt aus einem regulären Ausdruck und einer Ersatzzeichenfolge besteht. Optional können Sie für jeden dieser Schritte in der Sequenz die Ersetzung wiederholen, bis sich die Zeichenfolge nicht mehr ändert. Hier ist ein Beispielbeitrag (der das obige Problem nicht löst):
Regex Modifiers Replacement Repeat?
\b(\d) g |$1 No
|\d <none> 1| Yes
\D g <empty> No
In Anbetracht der Eingabe 123,456
würde diese Übermittlung die Eingabe wie folgt verarbeiten: Die erste Substitution wird einmal angewendet und ergibt:
|123,|456
Jetzt wird die zweite Ersetzung in einer Schleife angewendet, bis sich die Zeichenfolge nicht mehr ändert:
1|23,|456
11|3,|456
111|,|456
111|,1|56
111|,11|6
111|,111|
Und schließlich wird die dritte Ersetzung einmal angewendet:
111111
Beachten Sie, dass das Abbruchkriterium für Schleifen darin besteht, ob sich die Zeichenfolge ändert, und nicht, ob der reguläre Ausdruck eine Übereinstimmung gefunden hat. (Das heißt, es wird möglicherweise auch beendet, wenn Sie eine Übereinstimmung finden, die Ersetzung jedoch mit der Übereinstimmung identisch ist.)
Wertung
Ihre primäre Punktzahl ist die Anzahl der Substitutionsschritte in Ihrer Einreichung. Jede wiederholte Ersetzung zählt 10 Schritte. Das obige Beispiel würde also punkten 1 + 10 + 1 = 12
.
Im (nicht allzu unwahrscheinlichen) Fall eines Unentschieden ist die sekundäre Punktzahl die Summe der Größen aller Schritte. Fügen Sie für jeden Schritt den regulären Ausdruck ( ohne Begrenzer), die Modifikatoren und die Ersetzungszeichenfolge hinzu. Für das obige Beispiel wäre dies (6 + 1 + 3) + (3 + 0 + 2) + (2 + 1 + 0) = 18
.
Verschiedene Regeln
Sie können ein beliebiges Regex-Aroma verwenden (das Sie angeben sollten), aber alle Schritte müssen dasselbe Aroma verwenden. Außerdem müssen Sie nicht keine Funktionen der Wirtssprache Geschmack verwenden, wie Ersatz Rückrufe oder Perl- e
Modifikator, der Perl - Code auswertet. Alle Manipulationen müssen ausschließlich durch reguläre Ausdrücke erfolgen.
Beachten Sie, dass es von Ihrem Geschmack und Ihren Modifikatoren abhängt, ob jeder einzelne Ersatz alle Vorkommen oder nur ein einziges ersetzt. Wenn Sie beispielsweise die ECMAScript-Variante auswählen, ersetzt ein einzelner Schritt standardmäßig nur ein Vorkommen, es sei denn, Sie verwenden den g
Modifikator. Wenn Sie dagegen die .NET-Variante verwenden, werden bei jedem Schritt alle Vorkommen ersetzt.
Nehmen Sie für Sprachen mit unterschiedlichen Substitutionsmethoden für einzelne und globale Ersetzungen (z. B. Ruby's sub
vs. gsub
) an, dass einzelne Ersetzungen die Standardeinstellung sind, und behandeln Sie globale Ersetzungen wie einen g
Modifikator.
Testen
Wenn Sie .NET oder ECMAScript ausgewählt haben, können Sie Retina verwenden , um Ihre Einreichung zu testen (mir wurde gesagt, es funktioniert auch mit Mono). Für andere Geschmacksrichtungen müssen Sie wahrscheinlich ein kleines Programm in der Host-Sprache schreiben, das die Substitutionen der Reihe nach anwendet. In diesem Fall fügen Sie bitte dieses Testprogramm in Ihre Antwort ein.
quelle
Antworten:
.NET-Geschmack, Punktzahl: 2
Ich habe noch keine Lust, Golf zu spielen und
x
ignoriere nur Leerzeichen.Es wird zuerst
9876543210
an jeder Stelle eingefügt, dann werden die Originalzeichen und die Zeichen gelöscht, die nicht die aktuelle Ziffer der Summe sind.Der große reguläre Ausdruck (1346 Bytes ohne Leerzeichen und Kommentare):
Das ließ mich an die letzte Stufe von Manufactoria denken ... Aber ich denke, .NET Regex, das offensichtlich nicht mehr "normal" ist, kann alle Probleme in der PH lösen. Und das ist nur ein Algorithmus in L.
quelle
Prüfungsergebnis: 24
Ich denke das funktioniert ...
Ich habe noch nicht viel Zeit damit verbracht, die einzelnen regulären Ausdrücke zu spielen. Ich werde versuchen, bald eine Erklärung zu veröffentlichen, aber jetzt wird es spät. In der Zwischenzeit ist hier das Ergebnis zwischen den einzelnen Schritten:
Volles Perl-Programm:
quelle
Beliebiger Regexgeschmack, 41
Lass es uns unary versuchen.
d
Dient als Trennzeichen für die Ziffernreihenfolge,x
speichert den Wert. Zuerst heben wir jede Ziffer auf, drücken dann die x10-Multiplikatoren nach links, lassen dann alle Trennzeichen fallen, fügen die Multiplikatoren wieder ein und konvertieren dann jede Reihenfolge zurück in Ziffern.quelle
.NET Regex, 14
Nicht so gut wie die Lösung von user23013, aber es hat Spaß gemacht. Keiner der Ersetzungen hat Modifikatoren.
Der Grund für die .NET-Regex liegt nicht nur in den Bilanzkreisen. Ich habe gerade mit Retina getestet , das .NET verwendet, und festgestellt, dass das Aussehen mit variabler Länge sehr hilfreich ist.
Ersetzung 1 (Wiederholung = nein)
Regex:
Ersatz
Vertausche die beiden Zahlen und fülle sie auf, um die gleiche Anzahl führender Nullen zu erhalten.
Ersetzung 2 (Wiederholung = nein)
Regex:
Ersatz:
Fügen Sie vor jeder Zahl ein Leerzeichen ein
Ersatz 3 (Wiederholung = nein)
Ersatz:
Fügen Sie ein Carry-Bit (das
&0
) sowie die riesige Nachschlagetabelle von hinzu<c> <a> <b> <carry of a+b+c> <last digit of a+b+c>
.Ersetzung 4 (Wiederholung = ja)
Regex:
Ersatz:
Nimm die letzten Ziffern jeder Zahl und finde ihre (Summe, Übertragen). Geben Sie die Summe am Anfang der Zeichenfolge ein und ersetzen Sie den Übertrag.
Ersatz 5 (Wiederholung = nein)
Regex:
Ersatz:
Aufräumen.
Beispiellauf
(Durch das Kombinieren einiger Schritte kann ich 12 bekommen, aber da es ziemlich chaotisch wird und sowieso nicht gewinnt, denke ich, dass ich stattdessen diese elegantere Version beibehalten werde.)
quelle
Prüfungsergebnis:
50403121Vielen Dank für diese hervorragende Herausforderung. Diese Lösung ist nicht sehr elegant, aber angesichts der Einschränkungen konnte ich keine Möglichkeit finden, eine Ziffer generisch in der Ausgabe zu behandeln.
Diese Lösung bietet Erfassungsgruppen, die manchmal nicht übereinstimmen, und setzt voraus, dass sie in diesem Fall leer sind. Dies funktioniert in Perl, erzeugt jedoch normalerweise eine Warnung.
Vollständiges Perl-Codebeispiel mit Erläuterung und Ausdruck der Zwischenergebnisse:
Update: Ich konnte zwei der Regex-Schleifen miteinander kombinieren und 10 sparen.
Update 2: Ich habe es geschafft, die Konvertierung der eingegebenen Ziffern mit einer einzigen Regex zu knacken.
Update 3: Ich habe mich auf eine einzige Regex-Schleife reduziert.
quelle
${1}
anders$1
? Möglicherweise möchten Sie auch die Anzahl der Bytes bei Verbindungen angeben.\1
usw zu benutzen , stattdessen speichere ich ein paar zeichen .