Eine andere Lösung
Dies ist meiner Meinung nach eines der interessantesten Probleme auf der Website. Ich muss Deadcode dafür danken, dass er wieder nach oben geschoben wurde .
^((^|xx)(^|\3\4\4)(^|\4x{12})(^x|\1))*$
39 Bytes , ohne Bedingungen oder Zusicherungen ... irgendwie. Die Alternationen, wie sie verwendet werden ( ^|), sind in gewisser Weise eine Art Bedingung, um zwischen "erster Iteration" und "nicht erster Iteration" zu wählen.
Dieser reguläre Ausdruck funktioniert hier: http://regex101.com/r/qA5pK3/1
Sowohl PCRE als auch Python interpretieren den regulären Ausdruck korrekt und er wurde auch in Perl bis zu n = 128 getestet , einschließlich n 4 -1 und n 4 +1 .
Definitionen
Die allgemeine Technik ist dieselbe wie bei den anderen bereits veröffentlichten Lösungen: Definieren Sie einen selbstreferenzierenden Ausdruck, der bei jeder nachfolgenden Iteration einer Länge entspricht, die dem nächsten Term der Vorwärtsdifferenzfunktion D f mit einem unbegrenzten Quantifizierer ( *) entspricht. Eine formale Definition der Vorwärtsdifferenzfunktion:

Zusätzlich können auch Differenzfunktionen höherer Ordnung definiert werden:

Oder allgemeiner:

Die Vorwärtsdifferenzfunktion hat viele interessante Eigenschaften; es ist zu Sequenzen, was die Ableitung zu stetigen Funktionen ist. Zum Beispiel wird D f eines Polynoms n- ter Ordnung immer ein Polynom n-1- ter Ordnung sein, und für jedes i ist , wenn D f i = D f i + 1 , die Funktion f auf ähnliche Weise exponentiell dass die Ableitung von e x gleich sich selbst ist. Die einfachste diskrete Funktion, für die f = D f ist, ist 2 n .
f (n) = n 2
Bevor wir die obige Lösung untersuchen, wollen wir mit etwas Einfacherem beginnen: einem regulären Ausdruck, der Zeichenfolgen entspricht, deren Länge ein perfektes Quadrat ist. Untersuchen der Vorwärtsdifferenzfunktion:

Das heißt, die erste Iteration sollte mit einer Zeichenfolge der Länge 1 , die zweite mit einer Zeichenfolge der Länge 3 , die dritte mit einer Zeichenfolge der Länge 5 usw. übereinstimmen, und im Allgemeinen sollte jede Iteration mit einer Zeichenfolge übereinstimmen, die zwei länger als die vorherige ist. Der entsprechende reguläre Ausdruck folgt fast direkt aus dieser Aussage:
^(^x|\1xx)*$
Es ist ersichtlich, dass die erste Iteration nur mit einer übereinstimmt xund jede nachfolgende Iteration genau wie angegeben mit einer Zeichenfolge, die zwei länger als die vorherige ist. Dies impliziert auch einen erstaunlich kurzen perfekten Quadrattest in Perl:
(1x$_)=~/^(^1|11\1)*$/
Dieser reguläre Ausdruck kann weiter verallgemeinert werden, um mit jeder n- eckigen Länge übereinzustimmen:
Dreieckszahlen:
^(^x|\1x{1})*$
Quadratzahl:
^(^x|\1x{2})*$
Fünfeckige Zahlen:
^(^x|\1x{3})*$
Sechseckige Zahlen:
^(^x|\1x{4})*$
etc.
f (n) = n 3
Gehen Sie weiter zu n 3 und untersuchen Sie noch einmal die Vorwärtsdifferenzfunktion:

Es ist möglicherweise nicht sofort ersichtlich, wie dies implementiert werden kann. Daher untersuchen wir auch die zweite Differenzfunktion:

Die Vorwärtsdifferenzfunktion steigt also nicht um eine Konstante, sondern um einen linearen Wert. Es ist schön, dass der Anfangswert (' -1 th') von D f 2 Null ist, was eine Initialisierung bei der zweiten Iteration sichert. Der resultierende reguläre Ausdruck ist der folgende:
^((^|\2x{6})(^x|\1))*$
Die erste Iteration stimmt mit 1 überein , wie zuvor, die zweite mit einer längeren Zeichenfolge 6 ( 7 ), die dritte mit einer längeren Zeichenfolge 12 ( 19 ) usw.
f (n) = n 4
Die Vorwärtsdifferenzfunktion für n 4 :

Die zweite Vorwärtsdifferenzfunktion:

Die dritte Vorwärtsdifferenzfunktion:

Das ist hässlich. Die Anfangswerte für D f 2 und D f 3 sind beide ungleich Null, 2 bzw. 12 , was berücksichtigt werden muss. Sie haben wahrscheinlich schon herausgefunden, dass der reguläre Ausdruck diesem Muster folgt:
^((^|\2\3{b})(^|\3x{a})(^x|\1))*$
Weil der D f 3 muss eine Länge von Match 12 auf der zweiten Iteration, a ist notwendigerweise 12 . Da es sich jedoch mit jedem Term um 24 erhöht , muss die nächste tiefere Verschachtelung ihren vorherigen Wert zweimal verwenden, was bedeutet, dass b = 2 ist . Als letztes müssen Sie D f 2 initialisieren . Da D f 2 Einflüsse D f direkt, was letztlich ist das, was wir passen wollen, kann ihr Wert durch Einsetzen des entsprechende Atom initialisiert wird direkt in den regulären Ausdruck, in diesem Fall (^|xx). Der endgültige reguläre Ausdruck wird dann:
^((^|xx)(^|\3\4{2})(^|\4x{12})(^x|\1))*$
Höhere Aufträge
Ein Polynom fünfter Ordnung kann mit dem folgenden regulären Ausdruck verglichen werden:
^((^|\2\3{c})(^|\3\4{b})(^|\4x{a})(^x|\1))*$
f (n) = n 5 ist eine ziemlich einfache Übung, da die Anfangswerte sowohl für die zweite als auch für die vierte Vorwärtsdifferenzfunktion Null sind:
^((^|\2\3)(^|\3\4{4})(^|\4x{30})(^x|\1))*$
Für sechs Ordnungspolynome:
^((^|\2\3{d})(^|\3\4{c})(^|\4\5{b})(^|\5x{a})(^x|\1))*$
Für Polynome siebter Ordnung:
^((^|\2\3{e})(^|\3\4{d})(^|\4\5{c})(^|\5\6{b})(^|\6x{a})(^x|\1))*$
etc.
Beachten Sie, dass nicht alle Polynome auf genau diese Weise abgeglichen werden können, wenn einer der erforderlichen Koeffizienten nicht ganzzahlig ist. Zum Beispiel erfordert n 6 , dass a = 60 , b = 8 und c = 3/2 ist . Dies kann in diesem Fall umgangen werden:
^((^|xx)(^|\3\6\7{2})(^|\4\5)(^|\5\6{2})(^|\6\7{6})(^|\7x{60})(^x|\1))*$
Hier habe ich b auf 6 und c auf 2 geändert , die das gleiche Produkt wie die oben angegebenen Werte haben. Es ist wichtig, dass sich das Produkt nicht ändert, da a · b · c ·… die konstante Differenzfunktion steuert, die für ein Polynom sechster Ordnung D f 6 ist . Es sind zwei Initialisierungsatome vorhanden: eines zum Initialisieren von D f auf 2 , wie bei n 4 , und das andere zum Initialisieren der fünften Differenzfunktion auf 360 , während gleichzeitig die fehlenden zwei von b hinzugefügt werden .