Regex (PCRE lezzet), 66 (65🐌) bayt
İki regex dehası olan Martin Ender ve jaytea'nın bu kod golfüne regex çözümleri yazdığını görünce ilham aldım, kendimi sıfırdan yazdım. Ünlü prime-kontrol regex benim çözümümde hiçbir yerde görünmüyor.
Sizin için şımarık bazı regex sihri istemiyorsanız bunu okumayın. Bu sihri kendiniz bulmaya bir göz atmak istiyorsanız, ECMAScript regex’te bazı sorunları çözerek başlamanızı şiddetle tavsiye ederim:
- Asal sayıları eşleştir (bunu regex'te yapma konusunda henüz bilginiz yoksa)
- 2 kişilik güçlerin eşleştirilmesi (henüz yapmadıysanız). Ya da sadece Prime ve Powers'ı içeren Regex Golf ile çalışın . Hem Klasik hem de Teukon problem setlerini yaptığınızdan emin olun.
Kompozit olabilen (ancak olması gerekmeyen) N'nin sabit olduğu (yani regex'te, girişin değil) belirtilen N güçlerine uymanın en kısa yolunu bulun. Örneğin, 6'nın yetkileri.
N'in güçlerini eşleştirme yolunu bulun; burada N, sabit bir değerdir> = 2. Örneğin, mükemmel kareleri eşleştirin. (Isınma için, asal güçleri eşleştirin .)
Doğru çarpım ifadelerini eşleştirin. Üçgen sayıları eşleştirin.
Fibonacci sayılarıyla eşleşin (benim kadar deliyseniz) veya daha kısa bir şeye bağlı kalmak istiyorsanız, doğru üstelif ifadeleriyle eşleştirin (ısınma için, 2 değerinin gücünün 2. üssündeki logaritma ile eşleşin) bonus, herhangi bir sayı, istediğiniz şekilde yuvarlama) veya faktoring sayıları (ısınma, eşleştirme için ilkel sayılar ) için aynı işlemi yapın.
Bol sayıları eşleştir (benim kadar deliysen)
İstenen kesinlik için irrasyonel bir sayı hesaplayın (örneğin, girişi yuvarlanmış sonucu bir eşleşme olarak döndürerek 2'nin karekökü ile bölün)
( Yazdığım regex motoru yardımcı olabilir, çünkü sıradan matematik regex'lerinde çok hızlıdır ve doğal sayı aralıklarını test edebilen tek bir sayısal mod içerir (fakat aynı zamanda unary regex'leri veya unary sınırlayıcılarla) Varsayılan olarak ECMAScript uyumludur, ancak isteğe bağlı uzantıları vardır (seçmeli olarak PCRE'nin altkümelerini veya hatta başka bir regex motorunun sahip olmadığı bir moleküler görünüşü ekleyebilir).
Aksi halde, okumaya devam et ve ayrıca artan zorluktaki doğal sayı fonksiyonlarını (teukon'un bulmaca setinden başlayarak, bunların hepsini matematiğe çeviren, matematiksel olarak değil) başlatan ECMAScript regex'i zorlama yolunu zorlayan bu GitHub Gist'i (uyarı, birçok spoiler) okuyunuz. seyahat).
Bu sorunun diğer regex çözümlerinde olduğu gibi, girdi, bijektif unary'de virgülle ayrılmış ve kapsayıcı bir aralığı temsil eden iki sayı olarak verilir. Sadece bir numara döndürülür. Regex, aynı en küçük en büyük asal çarpanı paylaşan, aynı eşleşmeler olarak aynı sayıları döndüren tüm sayıları döndürecek şekilde değiştirilebilir, ancak değişken uzunluktaki göz kamaştırmasını gerektirir ve ya \K
bir göz kafasına yerleştirilir ya da sonucu eşleşme yerine bir yakalama olarak döndürür.
Burada, en küçük ana faktör tarafından tekrarlanan örtülü bölme işleminde kullanılan teknik , bir süre önce gönderdiğim uzunluğu dördüncü güç cevabı olan Maç dizelerinde kullanılan ile aynıdır .
Daha fazla uzatmadan:
((.+).*),(?!.*(?=\1)(((?=(..+)(\5+$))\6)*)(?!\2)).*(?=\1)\K(?3)\2$
Burada deneyebilirsiniz.
Ve boşluğu olan yorum, yorumlarla:
# No ^ anchor needed, because this algorithm always returns a
# match for valid input (in which the first number is less than
# or equal to the second number), and even in /g mode only one
# match can be returned. You can add an anchor to make it reject
# invalid ranges.
((.+).*), # \1 = low end of range; \2 = conjectured number that is the
# smallest number in the set of the largest prime factor of each
# number in the range; note, it is only in subsequent tests that
# this is implicitly confined to being prime.
# We shall do the rest of our work inside the "high end of range"
# number.
(?! # Assert that there is no number in the range whose largest prime
# factor is smaller than \2.
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
( # Subroutine (?3):
# Find the largest prime factor of tail, and leave it in tail.
# It will both be evaluated here as-is, and later as an atomic
# subroutine call. As used here, it is not wrapped in an atomic
# group. Thus after the return from group 3, backtracking back
# into it can increase the value of tail – but this won't mess
# with the final result, because only making tail smaller could
# change a non-match into a match.
( # Repeatedly divide tail by its smallest prime factor, leaving
# only the largest prime factor at the end.
(?=(..+)(\5+$)) # \6 = tool to make tail = \5 = largest nontrivial factor of
# current tail, which is implicitly the result of dividing it
# by its smallest prime factor.
\6 # tail = \5
)*
)
(?!\2) # matches iff tail < \ 2
)
# now, pick a number in the range whose largest prime factor is \2
.*(?=\1) # Cycle tail through all numbers in the range, starting with \1.
\K # Set us up to return tail as the match.
(?3) # tail = largest prime factor of tail
\2$ # Match iff tail == \2, then return the number whose largest
# prime factor is \2 as the match.
Algoritma, alt rutin çağrısını alt rutinin bir kopyasıyla değiştirerek ve eşleşmeyi \ K kullanmak yerine bir yakalama grubu olarak döndürerek ECMAScript'e kolayca aktarılabilir. Sonuç 80 bayt uzunluğundadır:
((x+)x*),(?!.*(?=\1)((?=(xx+)(\4+$))\5)*(?!\2)).*(?=\1)(((?=(xx+)(\8+$))\9)*\2$)
Çevrimiçi deneyin!
Doğru işlevsellik kaybı olmadan boyutu 1 bayt (66'dan 65 bayta ) düşürerek ((.+).*)
değiştirilebileceğini unutmayın; ancak regex katlanarak yavaşça patlar.((.+)+)
Çevrimiçi deneyin! (79 bayt ECMAScript üstel yavaşlama sürümü)