ReRegex , 294 275 Bytes
Durch Verwendung besserer 'Funktions'-Definitionen wurden 19 Bytes eingespart
Ich würde sagen, das ist ziemlich gut für eine Regex-Sprache.
Die Basisbibliothek ermöglicht die Konvertierung zwischen Unary und Decimal (was erforderlich ist, da die Challenge-Spezifikation explizit Decimal angibt), unterstützt jedoch nicht Binary. Also musste ich das als Teil des Skripts schreiben und 120 Bytes hinzufügen.
#import base
b(\d*):(_*)\2_b/b1$1:$2b/b(\d*):(_+)\2b/b0$1:$2b/b(\d+):b/$1/b:b/0/B(_*):1/B$1$1_:/B(_*):0/B$1$1:/B(_*):B/$1/j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/j(\d*),\1\d{0,7}:,?(.*)/,$2,/,((_+)_+),(\2),/,$1,/,(_+),(\1_*),/,$2,/^,(_*),$/d<$1>/j,b:u<(?#input)>b:
Probieren Sie es online!
Nach individuellen Regeln.
#import base
b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
^,(_*),$/d<$1>/
j,b:u<(?#input)>b:
Schritte
Zunächst importieren wir die 'base'-Bibliothek, die zwei reguläre Ausdrücke enthält. Eine, die sich u<numbers>
in eine unäre umwandelt . Und eine, die sich d<unary_underlines>
wieder in Dezimalzahlen umwandelt . Dies liegt daran, dass die Herausforderung IO in base10 erfordert.
Dann definieren wir eine Handvoll regulärer Ausdrücke, die unär in binär konvertieren.
b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/
Der erste b(\d*):(_*)\2_b/b1$1:$2b/
sucht nach b
, optional gefolgt von einigen Binärziffern, dann nach a :
, dann nach einer beliebigen Anzahl von Unterstreichungen, gefolgt von genau der gleichen Anzahl von Unterstreichungen plus einer und schließlich einer weiteren b
.
Wir ersetzen das dann durch b1
gefolgt von den Binärziffern von zuvor :
und nur der ersten Hälfte der Unterstriche und schließlich der letzten b
.
Dies überprüft also, ob der Unary nicht durch zwei teilbar ist, und stellt in diesem Fall 1 vor die Binärziffern und dividiert sie dann minus eins durch zwei.
Das zweite b(\d*):(_+)\2b/b0$1:$2b/
ist fast idendisch, prüft jedoch nicht auf ein Extra _
, dh es stimmt nur überein, wenn es durch zwei teilbar ist, und stellt in diesem Fall stattdessen ein voran 0
.
Die dritte prüft, ob wir keine unären Ziffern mehr haben, und entfernt in diesem Fall die Polsterung, um nur die binären Ziffern zu belassen.
Der letzte prüft, ob keine Binärziffern angegeben wurden, und geht dann einfach 0
.
Die nächste Gruppe von Regexen, die wir definieren, besteht darin, Binärdaten wieder in Unärdaten umzuwandeln. Sie sind etwas einfacher.
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
Die erste dieser Gruppe B(_*):1/B$1$1_:/
erkennt, ähnlich wie ihre Antithese, a B
, gefolgt von einer beliebigen Anzahl von unären Ziffern :1
. B
In diesem Fall wird nicht nach Übereinstimmungen gesucht, da immer nur nach einer Ziffer gesucht wird. Wenn dies zutrifft, verdoppelt es die zuvor übereinstimmende Anzahl von unären Ziffern und fügt eine hinzu und entfernt dann die eine.
Die zweite, B(_*):0/B$1$1:/
ist fast identisch mit der ersten, abgesehen von Übereinstimmungen mit a 0
anstelle von a 1
, und fügt keine zusätzliche unäre Ziffer hinzu.
Der letzte B(_*):B/$1/
Befehl prüft, ob keine Binärziffern mehr vorhanden sind, und packt den Unären aus, falls dies der Fall ist. Im Gegensatz zu seiner Antithese benötigt dies keinen speziellen 0-Fall.
Als nächstes definieren wir die j
regulären Ausdrücke, die als Aufteilungsfunktion fungieren.
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
Der erste j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
macht den größten Teil des schweren Hebens. Es wird gesucht j
, optional gefolgt von Binärziffern, die der "Inkrementierer" sind, dann ein Komma, gefolgt vom Inkrementierer, dann genau 8 Binärziffern, gefolgt vom Rest der Binärzahl, dann a :
. Die erste der 8 Ziffern wird an den Inkrementierer angehängt, wodurch dieser inkrementiert wird. Danach wird nach dem :
folgenden a alles andere als diese 8 Ziffern vom Binäreingang angehängt ,
. Also (wenn wir 2 statt 8 Ziffern verwenden j,1001:
würden ) würde es j1:1001:,01
dann werden j10:1001,01,11
. Darüber hinaus werden die angehängten Array-Elemente in B
s eingeschlossen, um sie wieder in unary umzuwandeln.
Die andere j(\d*),\1\d{0,7}:,?(.*)/,$2,/
prüft, ob nach dem Inkrementierer weniger als 8 Binärziffern übrig sind, und entfernt in diesem Fall alles andere als das in ,
s eingeschlossene Array . Z.B.,_,___,
Während und nach der Erstellung des Arrays definieren wir die Vergleichsregexes.
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
Bei der ersten ,((_+)_+),(\2),/,$1,/
Option wird ein Komma gefolgt von einer bestimmten Anzahl von Unterstrichen und einer weiteren, gefolgt von einem Komma gefolgt von der ersten Anzahl von Unterstrichen und einem Komma überprüft. Anschließend wird es durch die Gesamtzahl der Unterstriche im ersten Element ersetzt, das von ,
s umgeben ist.
Letzteres ,(_+),(\1_*),/,$2,/
sucht nach einem Komma, gefolgt von einer bestimmten Anzahl von Unterstrichen, gefolgt von einem weiteren Komma, der gleichen Menge oder mehreren Unterstrichen und einem letzten Komma. Dies wird stattdessen das richtige Element belassen.
Wenn schließlich noch ein passendes Element übrig ist ^,(_*),$
, entfernen wir die umgebenden Kommas und konvertieren zurück in das Dezimal-Via d<>
. Dann können keine regulären Ausdrücke mehr ausgelöst werden und die Ausgabe wird präsentiert.
Die Eingabe wird anfangs in die Vorlage eingefügt j,b:u<(?#input)>b:
, die zuerst die Dezimaleingabe in Unär umwandelt, z. B. 5
-> j,b:_____b:
, dann die resultierende Unärzahl in Binärzahl, j,101:
dann die Binärzahl aufteilt (was für das Beispiel nicht funktioniert), das größte Element erhält, konvertiert zurück zur Dezimalzahl und fertig.