Die Art des regulären Ausdrucks ist PCRE.
Schreiben Sie ein Programm, das eine gültige PCRE so ausgibt, dass alle natürlichen Zahlen zwischen m
und n
mit nichts anderem übereinstimmen. Führende Nullen sind nicht zulässig.
Zum Beispiel let m
and n
be 123
and 4321
, dann könnte das Programm ausgegeben werden
1(2[3-9]|[3-9]\d)|[2-9]\d\d|[123]\d\d\d|4([012]\d\d|3([01]\d|2[01]))
.
Dies entspricht exakt die gleiche Zeichenkette, so ^
und $
Anker ist implizit.
Man sollte versuchen, die beiden zu balancieren:
Der reguläre Ausdruck sollte eine angemessene Größe haben.
Der Code sollte kurz sein.
Optimieren wir für
code length in characters
+ 2 *regular expression length for input 123456 and 7654321
Randnotiz: Es ist interessant, wenn wir nachweisen können, dass der kürzeste reguläre PCRE-Ausdruck die Größe O (log n log log n) oder etwas anderes hat.
quelle
re_size*5 + prog_size
(kleiner = besser), wore_size
das Maximum fürm
undn
bis zu 5 Stellen ist. Es gibt viele andere Möglichkeiten, dies zu tun - wichtig ist, dass wir die Antworten bewerten können.print .*
in irgendeiner Sprache angeboten werden.if(min == 123456 && max == 7654321){print_hardcoded_regex}else{enumerate_range_and_join}
Antworten:
Perl, Punktzahl 455
191 Zeichen, 132 Regex-Länge
Eingang:
123456, 7654321
Update: Ich konnte dies weiter vereinfachen, als mir klar wurde, dass die meisten Muster mit Dingen wie endeten
\d{3}
. Diese machten nichts weiter als das Erzwingen einer Zeichenfolgenlänge - und dies sehr wiederholt, da sie bei jedem Begriff auftraten. Ich habe dies beseitigt, indem ich einen anderen Lookahead verwendet habe, um die Bedingung "kleiner als" zu erzwingen, und nur überprüft, ob entweder: 1) der erste Teil der Nummer die Eingabe nicht überschreitet oder 2) die Nummer weniger Stellen als die Eingabe hat. Dann überprüft die Haupt-Regex nur, ob es sich nicht um zu viele Ziffern handelt.Ich habe auch Peter Taylors Idee einer negativen Vorausschau aufgenommen, um die Bedingung "größer als" zu überprüfen.
Der Schlüssel zur Vereinfachung dieses Problems (zumindest für mich) bestand darin, den regulären Ausdruck in zwei Teile zu teilen: Ein Ausblick stellt sicher, dass die Anzahl nicht kleiner als das Minimum ist, und der Hauptteil des regulären Ausdrucks überprüft, ob er nicht größer als der ist maximal. Es ist ein bisschen albern für kleine Eingaben, aber es ist nicht so schlecht für große Eingaben.
Hinweis:
0|
Am Anfang wird alles, was mit einer Null beginnt, vom Abgleich ausgeschlossen. Dies ist aufgrund der rekursiven Natur der Regex-Funktion erforderlich: Innenteile der Übereinstimmung können mit Null beginnen, die gesamte Zahl jedoch nicht. Die Regex-Funktion kann den Unterschied nicht erkennen, daher habe ich eine Zahl, die mit Null beginnt, als Sonderfall ausgeschlossen.Eingang:
1, 4
Unangemessen lange Regex-Version, 29 Zeichen:
quelle
m
0 ist, müssen Sie 0 zulassen, obwohl es eine führende Null hat.Javascript, Punktzahl 118740839
Ich nehme an, ob Ihnen das gefällt oder nicht, hängt davon ab, wie Sie "eine angemessene Größe" definieren. :-)
quelle
Haskell 2063 + 2 * 151 = 2365
Es ist garantiert, dass der generierte reguläre Ausdruck die Länge O hat (log n log log n).
matchIntRange 12345 7654321
1(2(3(4(5[6-9]|[6-9]\d)|[5-9]\d\d)|[4-9]\d{3})|[3-9]\d{4})|[2-9]\d{5}|[1-6]\d{6}|7([0-5]\d{5}|6([0-4]\d{4}|5([0-3]\d{3}|4([012]\d\d|3([01]\d|2[01])))))
Der folgende Code ist eine einfache Version, die zum Verständnis des Algorithmus beiträgt, jedoch keine Optimierung zur Verbesserung der Regex-Größe vornimmt.
matchIntRange 123 4321
Der reguläre Ausdruck hat 680 Zeichen. Hier ist der Code
quelle
GolfScript (126 + 2 * 170 = 466)
Für die angegebenen Werte gibt es
Dissection zu folgen, aber die Grundidee ist , einen Codeblock zu definieren , die Karten eine einzelne natürliche Zahl mit einem regulären Ausdruck jede kleinere natürliche Zahl übereinstimmt, und dann die Eingänge drehen
lb
undub
in einen negativen Vorgriff - für (natürliche Zahl kleiner alslb
) in Kombination mit der Regex für (natürliche Zahl kleiner alsub+1
).Die Logik ist ziemlich kompliziert, daher ist sie selbst für GolfScript-Standards kryptisch. Bis ich eine detaillierte Präparation schreibe, ist hier eine Liste von Variablen:
quelle
|
dann ist das ein Fehler in Ihrer Regex-Engine, nicht in meinem Regex.(a|)
das tatsächlich gültig ist. In[1-0]
Ihrem vorherigen regulären Ausdruck funktionierte dies jedoch nicht in Perl oder einem Online-Tester, den ich ausprobiert habe.