Das Problem
Ich habe einige reguläre Ausdrücke, die ich in einem Code verwenden muss, aber ich verwende eine Programmiersprache, die Regex nicht unterstützt! Zum Glück weiß ich, dass der Teststring eine maximale Länge hat und nur aus druckbarem ASCII besteht.
Die Herausforderung
Sie müssen einen regulären Ausdruck und eine Zahl eingeben und n
jede Zeichenfolge ausgeben, die aus druckbarem ASCII (einschließlich ASCII-Codes 32 bis 126, bis
~
, ohne Tabulatoren oder Zeilenumbrüche) besteht und deren Länge der des regulären Ausdrucks entspricht oder n
dieser entspricht. Sie dürfen in Ihrem Code überhaupt keine integrierten regulären Ausdrücke oder Regex-Abgleichsfunktionen verwenden. Reguläre Ausdrücke sind auf Folgendes beschränkt:
- Literalzeichen (und Escapes, die ein Zeichen zum Literal machen, also
\.
ein Literal.
,\n
ist ein Literaln
(entspricht nurn
) und\w
entsprichtw
. Escape-Sequenzen müssen nicht unterstützt werden.) .
- Platzhalter (beliebiges Zeichen)- Zeichenklassen
[abc]
bedeuten "a oder b oder c" und[d-f]
bedeuten alles von d bis f (so, d oder e oder f). Die einzigen Zeichen, die in einer Zeichenklasse eine besondere Bedeutung haben, sind[
und]
(die immer ausgeblendet werden, machen Sie sich also keine Sorgen)\
(natürlich das Escape-Zeichen)^
am Anfang der Zeichenklasse (was eine Negation ist) ), und-
(das ist ein Bereich). |
- der OP-Operator, Wechsel.foo|bar
bedeutet entwederfoo
oderbar
, und(ab|cd)e
entspricht entwederabe
odercde
.*
- den vorherigen Token null oder mehrmals abgleichen, gierig (es wird versucht, so oft wie möglich zu wiederholen)+
- ein oder mehrmals wiederholt, gierig?
- Null oder einmal- Gruppierung mit Klammern gruppieren Token für
|
,*
.+
, oder?
Der reguläre Ausdruck für die Eingabe ist immer gültig (dh Sie müssen keine Eingaben wie ?abc
oder (foo
oder ungültige Eingaben verarbeiten). Sie können die Zeichenfolgen in beliebiger Reihenfolge ausgeben, aber jede Zeichenfolge darf nur einmal vorkommen (keine Duplikate ausgeben).
Die Testfälle
Input: .*
, 1
Output: (leere Zeichenkette), ,
!
, "
, ..., }
,~
Input: w\w+
, 3
Output: ww
,www
Input: [abx-z][^ -}][\\]
, 3
Output: a~\
, b~\
, x~\
, y~\
,z~\
Input: ab*a|c[de]*
, 3
Output: c
, cd
, ce
, aa
, cde
, ced
, cdd
, cee
,aba
Input: (foo)+(bar)?!?
, 6
Output: foo
, foo!
, foofoo
,foobar
Input: (a+|b*c)d
, 4
Output: ad
, cd
, aad
, bcd
, aaad
,bbcd
Input: p+cg
, 4
Output: pcg
,ppcg
Input: a{3}
, 4
Output:a{3}
Der Gewinner
Das ist Code-Golf , also gewinnt der kürzeste Code in Bytes!
quelle
|
macht sehr wenig Sinn. Es scheint verschachtelte Gruppen oder nicht zu behandelna|b|c
. Was ist falsch an der Verwendung der Standarderklärungen in Bezug auf die Bindungsstärke von Verkettung und Abwechslung? (Und Sie haben keine Entschuldigung dafür, den Sandkasten nicht zu benutzen)Antworten:
Haskell
757 705 700 692 679667Ausgabe:
Erläuterung: Dies ist eine Regex-Implementierung für Lehrbücher. R ist der Regex-Typ mit den Konstruktoren A (alternierend), L (wörtlich), T (dann) und E (leer / epsilon). Der übliche 'Stern' wird nicht angezeigt, da ich ihn während des Parsens als Alternative eingebunden habe (siehe '%'). 'm' führt die Simulation aus. Der Parser (Start bei 'rs = ....') ist nur ein rekursiver Abstieg. 'k' analysiert Bereiche. Die Funktion '#' erweitert Bereiche zu Alternationen.
quelle
Python 2.7
10691036950925897884871833822Diese Antwort scheint für einen Code Golf ziemlich lang zu sein, aber es gibt eine Menge Operatoren, die gehandhabt werden müssen, und ich weiß, welchen Zweck jedes Byte in dieser Antwort hat. Da es keine Antwort gibt, sende ich diese als Ziel für andere Benutzer, um sie zu schlagen. Sehen Sie, ob Sie eine kürzere Antwort machen können :).
Die zwei Hauptfunktionen sind,
f
die den regulären Ausdruck ab dem achteni
Zeichen analysieren undd
die passenden Zeichenfolgen unter Verwendungr
der regulären Ausdrücke erzeugen, in die wir rekursiv eingreifen können. und ein String-Suffix,s
das den bisher erzeugten Teil des Strings darstellt.Überprüfen Sie auch die Beispielausgabe und einen Test-Kabelbaum .
Beachten Sie, dass Registerkarten in der ursprünglichen Lösung bearbeitet wurden
expand
. Um die Anzahl der Zeichen in der ursprünglichen Verwendung zu zählenunexpand < regex.py | wc
.quelle
def E(a,b):c=a[:];c.extend(b);return c
zuE=lambda a,b:a[:].extend(b)
, ebenso fürA
elif isinstance(e,str):
, ich glaube, Sie könnten den Code in ändern:exec{'.':'for c in C:d(r,p,s+chr(c))','?':'d(r,p,s);d(r,p[:z],s)','*':'''c=p[:z]#newline for i in R(0,n+1):d(r,c,s);c+=[p[z]]''','+':"d(r,p+['*',p[z]],s)",'\\':'d(r,p,e[1]+s)'}.get(e,'d(r,p,e+s)')
(Beachten Sie, dass das#newline
eine neue Zeile ist) (Quelle: stackoverflow.com/a/103081/1896169 )