Tipps zum Golfen in der Netzhaut

10

Welche allgemeinen Tipps haben Sie zum Golfen in Retina ? Ich suche nach Ideen, die auf Code-Golf-Probleme im Allgemeinen angewendet werden können, die zumindest etwas spezifisch für Retina sind (z. B. "Kommentare entfernen" ist keine Antwort). Bitte posten Sie einen Tipp pro Antwort.

Als Referenz ist der Online - Compiler hier .

@ Sp3000 wies darauf hin, dass es auch Tipps für Regex Golf gibt . Die Antworten hier sollten sich speziell auf die Retina-Funktionen konzentrieren und nicht auf allgemeine Regex-Golftipps.

Digitales Trauma
quelle
2
Verwandte: Tipps für Regex Golf
Sp3000
Hmmm, ich habe mich zurückgehalten, weil Retina sich noch in der Entwicklung befindet und ich befürchtete, dass die meisten Antworten einfache Regex-Golftipps sein würden, die nicht sehr spezifisch für Retina sind. Aber wir könnten es genauso gut versuchen, denke ich ... :)
Martin Ender
@ MartinBüttner Du und einige andere haben mir viele gute Tipps und Hinweise gegeben, seit ich angefangen habe, mir Retina anzuschauen. Ich denke, es ist wahrscheinlich an der Zeit dafür. Ich habe eine Klarstellung hinzugefügt, dass allgemeine Regex-Tipps zu der verknüpften Frage gehen sollten.
Digitales Trauma
1
@ MartinBüttner Hier ist so gut wie jeder Ort zu fragen - ich habe mich schon eine Weile gefragt - aus Neugier, was ist die Inspiration für den Namen "Retina"? Ich nehme an, der "Re" -Teil ist für den regulären Ausdruck, aber was ist mit der "Tina"?
Digitales Trauma
3
@DigitalTrauma Ich habe versucht, ein schönes Wort zu finden, das als Akronym funktioniert, ist aber gescheitert. Das Wort "Netzhaut" war einigen Versuchen ziemlich nahe, und ich mochte das Wort. Ich habe es jedoch nie geschafft, es in ein Akronym umzuwandeln, und habe es seitdem aufgegeben. Also ja, das "re" ist eine Art für "reguläre Ausdrücke" und vielleicht das "n" für ".NET", aber letztendlich ist es nur ein Wort, das sich gut anhörte.
Martin Ender

Antworten:

3

Kombinieren Sie nach Möglichkeit Schleifen

Bei nicht trivialen Berechnungen verwenden Sie häufig mehrere Schleifen, um Daten zu verarbeiten:

+`stage1
+`stage2
+`stage3

Dies läuft also, stage1bis die Ausgabe konvergiert, dann stage2bis die Ausgabe konvergiert und dann stage3bis die Ausgabe konvergiert.

Es lohnt sich jedoch immer, die Phasen im Detail zu untersuchen. Manchmal ist es möglich, die Schleife stage1, stage2, stage3, stage1, stage2, stage3, ...stattdessen verschachtelt auszuführen (dies hängt stark davon ab, was die Stufen tatsächlich tun, aber manchmal nehmen sie vollständig orthogonale Änderungen vor oder funktionieren gut als Pipeline). In diesem Fall können Sie Bytes speichern, indem Sie sie in eine einzelne Schleife einschließen:

{`stage1
stage2
}`stage3

Wenn dies stage1die erste oder stage3die letzte Stufe des Programms ist, können Sie sogar eine dieser Klammern weglassen (was bedeutet, dass dadurch bereits Bytes für eine Schleife von zwei Stufen gespeichert werden können).

Eine neuere Verwendung dieser Technik ist in dieser Antwort zu sehen .

Martin Ender
quelle
2

Aufteilen von Saiten in gleich lange Stücke n

Wie in den meisten "normalen" Sprachen TMTOWTDI (es gibt mehr als einen Weg, dies zu tun). Ich gehe hier davon aus, dass die Eingabe keine Zeilenvorschübe enthält und dass "Aufteilen" das Aufteilen in Zeilen bedeutet. Es gibt jedoch zwei ganz unterschiedliche Ziele: Wenn die Länge der Zeichenfolge nicht ein Vielfaches der Blocklänge beträgt, möchten Sie den unvollständigen nachfolgenden Block beibehalten oder ihn verwerfen?

Einen unvollständigen nachlaufenden Block behalten

Im Allgemeinen gibt es drei Möglichkeiten, um die Netzhaut zu spalten. Ich präsentiere hier alle drei Ansätze, da sie einen größeren Unterschied machen können, wenn Sie versuchen, sie an ein verwandtes Problem anzupassen. Sie können einen Ersatz verwenden und jedem Spiel einen Zeilenvorschub hinzufügen:

.{n}
$&¶

Das sind 8 Bytes (oder etwas weniger, wenn n = 2oder n = 3weil Sie dann ..oder ...verwenden können). Dies hat ein Problem aber: es fügt einen zusätzlichen Zeilenvorschub , wenn die String - Länge ist ein Vielfaches der Blocklänge.

Sie können auch eine Split-Phase verwenden und die Tatsache nutzen, dass Captures im Split beibehalten werden:

S_`(.{n})

Die _Option entfernt die leeren Zeilen, die sich sonst ergeben würden, wenn die gesamte Zeichenfolge mit Übereinstimmungen abgedeckt würde. Dies sind 9 Bytes, es wird jedoch kein nachfolgender Zeilenvorschub hinzugefügt. Für n = 38 Bytes und für n = 27 Bytes. Beachten Sie, dass Sie insgesamt ein Byte speichern können, wenn die leeren Zeilen keine Rolle spielen (z. B. weil Sie nicht leere Zeilen verarbeiten und später ohnehin Zeilenvorschübe entfernen): Dann können Sie die entfernen _.

Die dritte Option ist die Verwendung einer Übereinstimmung. Mit der !Option können wir alle Übereinstimmungen drucken. Um den nachfolgenden Block einzuschließen, müssen wir jedoch eine variable Übereinstimmungslänge berücksichtigen:

M!`.{1,n}

Dies sind ebenfalls 9 Bytes und enthalten auch keinen nachgestellten Zeilenvorschub. Dies wird auch zu 8 Bytes, n = 3wenn Sie dies tun ..?.?. Beachten Sie jedoch, dass es auf 6 Bytes reduziert wird, n = 2da wir jetzt nur noch brauchen ..?. Beachten Sie auch, dass das Mgelöscht werden kann, wenn dies die letzte Stufe in Ihrem Programm ist, und auf jeden Fall ein Byte spart.

Verwerfen eines unvollständigen nachfolgenden Blocks

Dies wird sehr lang, wenn Sie versuchen, dies durch einen Ersatz zu tun, da Sie den nachfolgenden Block durch nichts (falls vorhanden) und auch durch einen Split ersetzen müssen. So können wir diese ignorieren. Interessanterweise ist es beim Match-Ansatz umgekehrt: Es wird kürzer:

M!`.{n}

Das ist 7 Bytes oder weniger für n = 2, n = 3. Beachten Sie erneut, dass Sie das weglassen können, Mwenn dies die letzte Stufe im Code ist.

Wenn Sie hier einen nachgestellten Zeilenvorschub wünschen, können Sie diesen durch Anhängen |$an den regulären Ausdruck erhalten.

Bonus: überlappende Stücke

Denken Sie daran, dass dies Mdie &Option hat, die überlappende Übereinstimmungen zurückgibt (was mit Regex normalerweise nicht möglich ist). Auf diese Weise können Sie alle überlappenden Blöcke (Teilzeichenfolgen) einer Zeichenfolge einer bestimmten Länge abrufen:

M!&`.{n}
Martin Ender
quelle
Ist es irgendwie möglich, eine Saite mit variabler Länge genau in zwei Hälften zu teilen? So 123456wird 123\n456und 1234567890wird 12345\n67890?
Kevin Cruijssen
1
@ KevinCruijssen Ich glaube nicht, dass ich dafür eine spezielle Funktion hinzugefügt habe. Sie müssen wahrscheinlich Ausgleichsgruppen verwenden: tio.run/##K0otycxLNPyvquGe8D/YIEHD3sZWQ09TW1PD3hbI1jW0A3JUNP//… Wenn Ihnen ein nachlaufender Zeilenvorschub nichts ausmacht, können Sie den auslassen ?=.
Martin Ender
Ich konnte die Herausforderung dort bewältigen, wo ich dachte, ich brauche sie anders, aber die Ausgleichsgruppen sind in der Tat sehr nützlich! Ich wusste, dass es etwas in diese Richtung sein musste, aber meine Regex / Retina-Fähigkeiten sind bei weitem nicht gut genug. Danke für die Antwort! :)
Kevin Cruijssen