Başka bir çözüm
Bu, bence sitedeki en ilginç problemlerden biri. Zirveye geri döndüğüm için deadcode'a teşekkür etmeliyim .
^((^|xx)(^|\3\4\4)(^|\4x{12})(^x|\1))*$
39 bayt , herhangi bir şartlandırma veya iddia olmadan ... tür. Değişimler, kullanıldıkları gibi ( ^|
), "ilk yineleme" ve "ilk yineleme değil" arasında seçim yapmak için bir şekilde koşullu bir türdür.
Bu regex burada çalışmak için görülebilir: http://regex101.com/r/qA5pK3/1
PCRE'nin ve Python Hem doğru düzenli ifade yorumlamak ve bu da kadar Perl test edilmiştir n = 128 de dahil olmak üzere, n, 4 -1 ve n, 4 + 1 .
Tanımlar
Genel teknik daha önce yayınlanan diğer çözümlerde aynıdır: ileri fark fonksiyonu, bir sonraki terime eşit sonraki her tekrarında bir uzunluğa uyan bir kendi kendine referans ifade tanımlayan D f sınırsız nicelik ile, ( *
). İleri fark fonksiyonunun resmi bir tanımı:
Ek olarak, daha yüksek dereceli fark fonksiyonları da tanımlanabilir:
Veya daha genel olarak:
İleri fark fonksiyonunun birçok ilginç özelliği vardır; türevin ne olduğunu sürekli fonksiyonlara göre sıralar. Örneğin, D f bir bölgesinin N inci polinom her zaman olacaktır , n-1 inci polinom ve herhangi i , eğer D f i = D f i + 1 , işlev f de aynı şekilde, üstel türevi olduğu e x kendi eşittir. En basit ayrık fonksiyonu olan f = D f olan 2 , n .
f (n) = n- 2
Yukarıdaki çözümü incelemeden önce, biraz daha kolay bir şeyle başlayalım: uzunlukları mükemmel bir kare olan dizelerle eşleşen bir regex. İleri fark fonksiyonunun incelenmesi:
Yani, birinci yineleme uzunluğu 1 olan bir dize, ikincisi uzunluk 3 olan bir dize, üçüncü uzunluk 5 olan bir dize vb. İle eşleşmelidir ve genel olarak, her yineleme öncekinden iki daha uzun olan bir dizeyle eşleşmelidir. Karşılık gelen regex hemen hemen bu ifadeden izler:
^(^x|\1xx)*$
İlk yinelemenin yalnızca biriyle eşleşeceği x
ve sonraki her yinelemenin, tam olarak belirtildiği gibi öncekinden iki daha uzun bir dizeyle eşleşeceği görülebilir . Bu aynı zamanda perl'de şaşırtıcı derecede kısa, mükemmel bir kare testi anlamına gelir:
(1x$_)=~/^(^1|11\1)*$/
Bu normal ifade ayrıca, herhangi bir maç için genelleştirilebilir N -gonal uzunluğu:
Üçgen sayılar:
^(^x|\1x{1})*$
Kare sayılar:
^(^x|\1x{2})*$
Beşgen sayılar:
^(^x|\1x{3})*$
Altıgen sayılar:
^(^x|\1x{4})*$
vb.
f (n) = n- 3
İçin taşıma n 3 kez daha ileri fark fonksiyonunu inceleyerek,:
Bunun nasıl uygulanacağı hemen belli olmayabilir, bu yüzden ikinci fark fonksiyonunu da inceleriz:
Dolayısıyla, ileri doğru fark fonksiyonu sabit bir şekilde artmaz, aksine doğrusal bir değer artar. It 'güzel ilk ( 'o -1 inci') değeri D f 2 ikinci tekrarında bir başlatma kaydeder sıfırdır. Ortaya çıkan regex şudur:
^((^|\2x{6})(^x|\1))*$
İlk yineleme , eskisi gibi 1 ile eşleşir , ikincisi daha uzun bir dizeyle 6 ( 7 ), üçüncü ise daha uzun bir dizeyle 12 ( 19 ), vb. Eşleşir.
f (n) = n- 4
N 4 için ileri fark fonksiyonu :
İkinci ileri fark fonksiyonu:
Üçüncü ileri fark fonksiyonu:
Şimdi bu çirkin. İçin başlangıç değerleri, D f 2 ve D f 3 , her iki sigara sıfır, 2 ve 12 gerekecektir sırasıyla muhasebeleşmesine. Muhtemelen şimdiye kadar regex'in bu modeli takip edeceğini öğrendiniz:
^((^|\2\3{b})(^|\3x{a})(^x|\1))*$
Çünkü D f 3 arasında bir uzunluğa eşleşmelidir 12 ikinci tekrarında, bir zorunlu olan 12 . Ancak , her terim 24 arttığı için , bir sonraki derin yuvalama, b = 2 anlamına gelecek şekilde önceki değerini iki kez kullanmalıdır . Yapılacak son şey, D f'yi başlatmaktır. 2 . Çünkü D f 2 etkiler D f maç için istiyoruz, ne de olsa, doğrudan, değeri, bu durumda, düzenli ifade doğrudan uygun atomu sokulmasıyla başlatıldı edilebilir(^|xx)
. Son regex sonra olur:
^((^|xx)(^|\3\4{2})(^|\4x{12})(^x|\1))*$
Daha Yüksek Siparişler
Beşinci dereceden bir polinom aşağıdaki regex ile eşleştirilebilir:
^((^|\2\3{c})(^|\3\4{b})(^|\4x{a})(^x|\1))*$
f (n) = n 5 , hem ikinci hem de dördüncü ileri fark fonksiyonlarının başlangıç değerleri sıfır olduğundan, oldukça kolay bir egzersizdir:
^((^|\2\3)(^|\3\4{4})(^|\4x{30})(^x|\1))*$
Altı dereceli polinomlar için:
^((^|\2\3{d})(^|\3\4{c})(^|\4\5{b})(^|\5x{a})(^x|\1))*$
Yedinci dereceden polinomlar için:
^((^|\2\3{e})(^|\3\4{d})(^|\4\5{c})(^|\5\6{b})(^|\6x{a})(^x|\1))*$
vb.
Gerekli katsayıların herhangi biri tamsayı değilse, tüm polinomların tam olarak bu şekilde eşleştirilemeyeceğini unutmayın. Örneğin, n, 6 gerektirir , a = 60 , b = 8 olduğu ve C = 3/2 . Bu, bu durumda, bu konuda çalışılabilir:
^((^|xx)(^|\3\6\7{2})(^|\4\5)(^|\5\6{2})(^|\6\7{6})(^|\7x{60})(^x|\1))*$
Burada değiştirdik b için , 6 ve C için 2 yukarıda belirtilen değerleri aynı ürün olması. Bu ürün olarak, değişmez önemlidir bir · b · c · ... kontroller altıncı dereceden bir polinom içindir sabit fark fonksiyonu, D f 6 . Bir başlatmak için: Bu iki başlatma atomu vardır D f için 2 ile olduğu gibi, n- 4 ve diğer beşinci fark fonksiyonu başlatmak için 360 aynı zamanda eksik iki eklenirken, b .