Regex (ECMAScript), 276 205 201 193 189 bayt
Farklı asal faktörlerin çarpımlarının (üstlerinin) karşılaştırılması, ECMAScript regex ile çözme için ilginç bir sorundur - bir döngünün yinelemeleriyle devam eden geri dönüşlerin olmaması, bir şeyi saymak için zorlaştırır. Söz konusu sayısal özelliği saymak bile mümkün olsa da, genellikle daha dolaylı bir yaklaşım daha iyi golf oynamayı sağlar.
Diğer ECMA regex yayınlarımda olduğu gibi, bir spoiler uyarısı vereceğim : ECMAScript regex’te sıradan matematik problemlerini nasıl çözeceğinizi öğrenmenizi şiddetle tavsiye ederim. Benim için büyüleyici bir yolculuk oldu ve bunu denemek isteyebilecek herhangi biri için, özellikle de sayı teorisine ilgi duyanlar için onu mahvetmek istemiyorum. Birbiri ardına çözmek için art arda spoiler etiketli önerilen sorunların bir listesi için bu önceki yazıya bakın .
Bu yüzden , sizin için şımarık bazı gelişmiş regex sihrini istemiyorsanız, daha fazla okumayın . Bu sihri kendiniz bulmaya bir göz atmak isterseniz, yukarıda belirtilen bağlantıda belirtildiği gibi ECMAScript regex'teki bazı sorunları çözerek başlamanızı şiddetle tavsiye ederim.
Daha önce geliştirdiğim bir regex'in ana yükünün bu zorluğa çok uygun olduğu ortaya çıktı. En yüksek çokluğun asalını bulan regex'tir . Bunun için ilk çözüm çok uzun oldu ve daha sonra ilk yolu aşağı aşamalarında bunu golfed moleküler lookahead kullanmak için yeniden sonra ve geri düz ECMAScript'e için taşıma için gelişmiş bir teknik kullanılarak moleküler lookahead eksikliği etrafında çalışması ve daha sonra Orijinal ECMAScript çözümünden çok daha küçük olması için aşağı doğru golf oynamaya.
Bu soruna uygulanan söz konusu regex'ten gelen bölüm, tüm ana faktörleri paylaşan en küçük N faktörü olan Q'yu bulan ilk adımdır. Bu sayıya sahip olduktan sonra, N'nin bir "sabit üs sayısı" olduğunu göstermek için tek yapmamız gereken, artık yapamayana kadar Q'yu N'ye bölmek; sonuç 1 ise, tüm primler eşit çokluğa sahiptir.
Q bulmak için önceden geliştirilen algoritmamı kullanarak bir cevap gönderdikten sonra, bunun tamamen farklı bir şekilde hesaplanabileceğini fark ettim: En büyük N kare-kare faktörünü bulun ( Carmichael sayı regex'im ile aynı algoritmayı kullanarak ). Görünüşe göre, bu, moleküler bakış açılarının ve değişken uzunluktaki gözlerin yokluğunun (daha önce kullanılan ileri teknikten çekmeye gerek kalmaması) etrafındaki adım atma konusunda hiçbir zorluk * yaratmıyor ve 64 byte daha kısa! Ek olarak, kare içermeyen N ve asal N'i farklı özel durumlar olarak ele almanın karmaşıklığını ortadan kaldırarak, bu çözümden 7 baytı daha düşürür.
(Eskiden burada Q hesaplamasını yapmak için kullanılan ileri teknik gerektiren başka problemler var, ancak şu anda hiçbiri PPCG postalarım tarafından temsil edilmiyor.)
Çokluk testini ardışık primerler testinden önce koydum çünkü ikincisi çok daha yavaş; daha hızlı bir şekilde başarısız olabilecek testleri koymak, ilk önce düzgün dağılmış giriş için regex'i daha hızlı hale getirir. Ayrıca ilk önce koymak daha iyidir, çünkü daha fazla geri dönüş kullanır (eğer iki basamaklı olsaydı daha pahalı olurdu).
Bölümün bölene eşit veya ondan daha büyük olması garanti edildiğinde daha fazla bölünmeyi daha da kısaltabilecek bir hile kullanarak bu regex'ten (193 → 189) 4 bayt bırakmayı başardım .
^(?=(|(x+)\2*(?=\2$))((?=(xx+?)\4*$)(?=(x+)(\5+$))\6(?!\4*$))*x$)(?=.*$\2|((?=((x*)(?=\2\9+$)x)(\8*$))\10)*x$)(?!(((x+)(?=\13+$)(x+))(?!\12+$)(x+))\11*(?=\11$)(?!(\15\14?)?((xx+)\18+|x?)$))
Çevrimiçi deneyin!
# For the purposes of these comments, the input number = N.
^
# Assert that all of N's prime factors are of equal multiplicity
# Step 1: Find Q, the largest square-free factor of N (which will also be the smallest
# factor of N that has all the same prime factors as N) and put it in \2.
# If N is square-free, \2 will be unset.
(?=
# Search through all factors of N, from largest to smallest, searching for one that
# satisfies the desired property. The first factor tried will be N itself, for which
# \2 will be unset.
(|(x+)\2*(?=\2$)) # for factors < N: \2 = factor of N; tail = \2
# Assert that tail is square-free (its prime factors all have single multiplicity)
(
(?=(xx+?)\4*$) # \4 = smallest prime factor of tail
(?=(x+)(\5+$)) # \5 = tail / \4 (implicitly); \6 = tool to make tail = \5
\6 # tail = \5
(?!\4*$) # Assert that tail is no longer divisible by \4, i.e. that that
# prime factor was of exactly single multiplicity.
)*x$
)
# Step 2: Require that either \2 is unset, or that the result of repeatedly
# dividing tail by \2 is 1.
(?=
.*$\2
|
(
# In the following division calculation, we can skip the test for divisibility
# by \2-1 because it's guaranteed that \2 <= \8. As a result, we did not need to
# capture \2-1 above, and can use a better-golfed form of the division.
(?=
( # \8 = tail / \2
(x*) # \9 = \8-1
(?=\2\9+$)
x
)
(\8*$) # \10 = tool to make tail = \8
)
\10 # tail = \8
)*
x$ # Require that the end result is 1
)
# Assert that there exists no trio of prime numbers such that N is divisible by the
# smallest and largest prime but not the middle prime.
(?!
( # \11 = a factor of N
( # \12 = a non-factor of N between \11 and \13
(x+)(?=\13+$) # \13 = a factor of N smaller than \11
(x+) # \14 = tool (with \15) to make tail = \13
)
(?!\12+$)
(x+) # \15 = tool to make tail = \12
)
\11*(?=\11$) # tail = \11
# Assert that \11, \12, and \13 are all prime
(?!
(\15\14?)? # tail = either \11, \12, or \13
((xx+)\18+|x?)$
)
)
* N'nin karesiz olması için özel bir durum olmadan, moleküler görünüşle hala daha temiz. Bu işlem 6 baytlık bir düşüşle 195 187 183 baytlık bir çözüm üretiyor :
^(?=(?*(x+))\1*(?=\1$)((?=(xx+?)\3*$)(?=(x+)(\4+$))\5(?!\3*$))*x$)(?=((?=((x*)(?=\1\8+$)x)(\7*$))\9)*x$)(?!(((x+)(?=\12+$)(x+))(?!\11+$)(x+))\10*(?=\10$)(?!(\14\13?)?((xx+)\17+|x?)$))
# For the purposes of these comments, the input number = N.
^
# Assert that all of N's prime factors are of equal multiplicity
# Step 1: Find Q, the largest square-free factor of N (which will also be the smallest
# factor of N that has all the same prime factors as N) and put it in \1.
(?=
(?*(x+)) # \1 = proposed factor of N
\1*(?=\1$) # Assert that \1 is a factor of N; tail = \1
# Assert that tail is square-free (its prime factors all have single multiplicity)
(
(?=(xx+?)\3*$) # \3 = smallest prime factor of tail
(?=(x+)(\4+$)) # \4 = tail / \3 (implicitly); \5 = tool to make tail = \4
\5 # tail = \4
(?!\3*$) # Assert that tail is no longer divisible by \3, i.e. that that
# prime factor was of exactly single multiplicity.
)*x$
)
# Step 2: Require that the result of repeatedly dividing tail by \1 is 1.
(?=
(
# In the following division calculation, we can skip the test for divisibility
# by \1-1 because it's guaranteed that \2 <= \8. As a result, we did not need to
# capture \1-1 above, and can use a better-golfed form of the division.
(?=
( # \7 = tail / \1
(x*) # \8 = \7-1
(?=\1\8+$)
x
)
(\7*$) # \9 = tool to make tail = \7
)
\9 # tail = \7
)*
x$ # Require that the end result is 1
)
# Assert that there exists no trio of prime numbers such that N is divisible by the
# smallest and largest prime but not the middle prime.
(?!
( # \10 = a factor of N
( # \11 = a non-factor of N between \10 and \12
(x+)(?=\12+$) # \12 = a factor of N smaller than \10
(x+) # \13 = tool (with \14) to make tail = \12
)
(?!\11+$)
(x+) # \14 = tool to make tail = \11
)
\10*(?=\10$) # tail = \10
# Assert that \10, \11, and \12 are all prime
(?!
(\14\13?)? # tail = either \10, \11, or \12
((xx+)\17+|x?)$
)
)
Burada değişken uzunluktaki gözbebekine taşınır:
Regex (2018 ECMAScript), 198 195 194 186 182 bayt
^(?=(x+)(?=\1*$)(?<=^x((?<!^\5*)\3(?<=(^\4+)(x+))(?<=^\5*(x+?x)))*))((?=((x*)(?=\1\8+$)x)(\7*$))\9)*x$(?<!(?!(\14\16?)?((xx+)\12+|x?)$)(?<=^\13+)((x+)(?<!^\15+)((x+)(?<=^\17+)(x+))))
Çevrimiçi deneyin!
# For the purposes of these comments, the input number = N.
^
# Assert that all of N's prime factors are of equal multiplicity
# Step 1: Find Q, the largest square-free factor of N (which will also be the smallest
# factor of N that has all the same prime factors as N) and put it in \1.
(?=
(x+)(?=\1*$) # \1 = factor of N; head = \1
(?<= # This is evaluated right-to-left, so please read bottom to top.
^x
(
(?<!^\5*) # Assert that head is no longer divisible by \6, i.e. that
# that prime factor was of exactly single multiplicity.
\3 # head = \4
(?<=(^\4+)(x+)) # \4 = head / \5 (implicitly); \3 = tool to make head = \4
(?<=^\5*(x+?x)) # \5 = smallest prime factor of head
)*
)
)
# Step 2: Require that the result of repeatedly dividing tail by \1 is 1.
(
# In the following division calculation, we can skip the test for divisibility
# by \1-1 because it's guaranteed that \2 <= \8. As a result, we did not need to
# capture \1-1 above, and can use a better-golfed form of the division.
(?=
( # \7 = tail / \1
(x*) # \8 = \7-1
(?=\1\8+$)
x
)
(\7*$) # \9 = tool to make tail = \7
)
\9 # tail = \7
)*
x$ # Require that the end result is 1
# Assert that there exists no trio of prime numbers such that N is divisible by the
# smallest and largest prime but not the middle prime.
# This is evaluated right-to-left, so please read bottom to top, but switch back to
# reading top to bottom at the negative lookahead.
(?<!
# Assert that \13, \15, and \17 are all prime.
(?!
(\14\16?)? # tail = either \13, \15, or \17
((xx+)\12+|x?)$
)
(?<=^\13+)
( # tail = \13
(x+) # \14 = tool to make tail = \15
(?<!^\15+)
(
(x+) # \16 = tool (with \14) to make tail = \17
(?<=^\17+)(x+) # \17 = a factor of N smaller than \13
) # \15 = a non-factor of N between \13 and \17
) # \13 = a factor of N
)