別の解決策
これは、私の意見では、このサイトで最も興味深い問題の1つです。トップに戻してくれたデッドコードに感謝する必要があります。
^((^|xx)(^|\3\4\4)(^|\4x{12})(^x|\1))*$
39バイト、条件またはアサーションなし...並べ替え。使用されている代替(^|
)は、ある意味で「最初の反復」と「最初の反復ではない」を選択するための条件の一種です。
この正規表現は、http://regex101.com/r/qA5pK3/1で機能することが確認できます。
PCREとPythonの両方が正しく正規表現を解釈し、それはまた、アップにPerlで試験されたN = 128を含む、N 4 -1、及びN 4 +1。
定義
一般的な手法は、既に投稿されている他のソリューションと同じです:後続の各反復で、前方差分関数の次の項D fに等しい長さに無制限の量指定子(*
)で一致する自己参照式を定義します。前方差分関数の正式な定義:
さらに、高階差分関数も定義できます。
または、より一般的に:
前方差分関数には多くの興味深い特性があります。それは、連続関数に対する微分が何であるかをシーケンスすることです。たとえば、n次多項式のD fは常にn-1次多項式であり、任意のiについて、D f i = D f i + 1の場合、関数fはほぼ同じように指数関数になります。e xの導関数がそれ自体に等しいこと。f = D fが2 nである最も単純な離散関数。
f(n)= n 2
上記の解決策を検討する前に、少し簡単なものから始めましょう。長さが完全な正方形である文字列に一致する正規表現です。前方差分関数を調べる:
つまり、最初の反復は長さ1のストリングと一致し、2番目は長さ3のストリング、3番目は長さ5のストリングと一致する必要がありますなどに一致する必要があります。一般に、各反復は前より2つ長い文字列に一致する必要があります。対応する正規表現は、このステートメントからほぼ直接続きます。
^(^x|\1xx)*$
最初の反復は1つだけに一致することがわかります x
に一致し、後続の各反復は、指定されたとおりに、前の反復よりも2つ長い文字列に一致することがわかります。これは、perlでの驚くほど短い完全な正方形テストも意味します。
(1x$_)=~/^(^1|11\1)*$/
この正規表現は、任意のn角の長さに一致するようにさらに一般化できます。
三角数字:
^(^x|\1x{1})*$
平方数:
^(^x|\1x{2})*$
五角形の数字:
^(^x|\1x{3})*$
六角形の数字:
^(^x|\1x{4})*$
等
f(n)= n 3
移動のn 3再び前進差分機能を調べ、:
これを実装する方法はすぐには明らかではない可能性があるため、2番目の差分関数も調べます。
したがって、前方差分関数は定数ではなく、線形値で増加します。D f 2の初期( ' -1 th')値がゼロであると便利です。これにより、2回目の反復で初期化が保存されます。結果の正規表現は次のとおりです。
^((^|\2x{6})(^x|\1))*$
前と同じように、最初の反復は1に一致し、2番目は6長い文字列(7)に一致し、3番目は12長い文字列(19)に一致します)に。
f(n)= n 4
n 4の前方差分関数:
2番目の前方差分関数:
3番目の前方差分関数:
今ではthatいです。D f 2およびD f 3の初期値は両方ともゼロではなく、それぞれ2および12であり、これを考慮する必要があります。おそらく、正規表現は次のパターンに従うことになるでしょう。
^((^|\2\3{b})(^|\3x{a})(^x|\1))*$
D f 3は12の長さに一致する必要があるため第2の反復では、必然的である12。しかし、それは各項ごとに24ずつ増加するため、次のより深いネストは、以前の値を2回使用する必要があり、b = 2を意味します。最後に行うことは、D f 2を初期化することです。D f 2は最終的に一致させるD fに直接影響するため、この場合、適切なアトムを正規表現に直接挿入することでその値を初期化できます。最終的な正規表現は次のようになります。(^|xx)
^((^|xx)(^|\3\4{2})(^|\4x{12})(^x|\1))*$
高次
5次多項式は、次の正規表現と照合できます。
^((^|\2\3{c})(^|\3\4{b})(^|\4x{a})(^x|\1))*$
f(n)= n 5は、2番目と4番目の前方差分関数の両方の初期値がゼロであるため、かなり簡単な練習です。
^((^|\2\3)(^|\3\4{4})(^|\4x{30})(^x|\1))*$
6次多項式の場合:
^((^|\2\3{d})(^|\3\4{c})(^|\4\5{b})(^|\5x{a})(^x|\1))*$
7次多項式の場合:
^((^|\2\3{e})(^|\3\4{d})(^|\4\5{c})(^|\5\6{b})(^|\6x{a})(^x|\1))*$
等
必要な係数のいずれかが非整数である場合、すべての多項式がこの方法で正確に一致するわけではないことに注意してください。たとえば、n 6では、a = 60、b = 8、およびc = 3/2が必要です。この場合、これを回避できます:
^((^|xx)(^|\3\6\7{2})(^|\4\5)(^|\5\6{2})(^|\6\7{6})(^|\7x{60})(^x|\1))*$
ここで、bを6に変更し、cを2に変更しました。これらの値は上記の値と同じです。a・b・c・…が一定の差関数を制御するため、積が変化しないことが重要です。これは、6次多項式ではD f 6です。初期化アトムが2つあります:1つは初期化するはn 4のようにD fを2は5番目の差分関数を360に初期化すると同時にbから欠落している2つを追加します。