Regex (ECMAScript), 276 205 201 193 189 byte
Membandingkan multiplisitas (eksponen) dari faktor prima yang berbeda adalah masalah yang menarik untuk dipecahkan dengan regex ECMAScript - kurangnya referensi yang bertahan melalui iterasi dari loop membuatnya menjadi tantangan untuk menghitung apa pun. Sekalipun menghitung sifat numerik yang dipermasalahkan adalah mungkin, seringkali pendekatan yang lebih tidak langsung membuat golf lebih baik.
Seperti dengan posting regex ECMA saya yang lain, saya akan memberikan peringatan spoiler: Saya sangat merekomendasikan belajar bagaimana memecahkan masalah matematika unary di ECMAScript regex. Ini adalah perjalanan yang menarik bagi saya, dan saya tidak ingin merusaknya untuk siapa pun yang mungkin ingin mencobanya sendiri, terutama mereka yang tertarik pada teori bilangan.Lihat posting ini sebelumnya untuk daftar masalah yang direkomendasikan untuk ditandai dengan spoiler bertanda satu per satu.
Jadi jangan membaca lebih jauh jika Anda tidak ingin beberapa sihir regex unary canggih dimanjakan untuk Anda . Jika Anda ingin mencoba mencari tahu sendiri keajaiban ini, saya sangat menyarankan memulai dengan menyelesaikan beberapa masalah dalam ECMAScript regex sebagaimana diuraikan dalam pos yang ditautkan di atas.
Payload utama dari regex yang saya kembangkan sebelumnya ternyata sangat berlaku untuk tantangan ini. Itu adalah regex yang menemukan yang terbaik dari multiplisitas tertinggi . Solusi pertama saya untuk itu sangat panjang, dan saya kemudian turun golf secara bertahap, pertama menulis ulang untuk menggunakan lookahead molekuler , dan kemudian porting kembali ke ECMAScript menggunakan teknik canggih untuk mengatasi kekurangan lookahead molekuler , dan kemudian bermain golf menjadi jauh lebih kecil dari solusi ECMAScript polos asli.
Bagian dari regex yang berlaku untuk masalah ini adalah langkah pertama, yang menemukan Q, faktor terkecil N yang memiliki semua faktor prima. Setelah kita memiliki angka ini, yang harus kita lakukan untuk menunjukkan bahwa N adalah "angka eksponen konstan" dibagi N dengan Q sampai kita tidak bisa lagi; jika hasilnya 1, semua bilangan prima memiliki multiplisitas yang sama.
Setelah mengirimkan jawaban menggunakan algoritme yang saya kembangkan sebelumnya untuk menemukan Q, saya menyadari bahwa itu dapat dihitung dengan cara yang sama sekali berbeda: Temukan faktor N bebas kuadrat terbesar (menggunakan algoritme yang sama dengan regex nomor Carmichael saya ). Ternyata, ini tidak menimbulkan kesulitan sama sekali * dalam hal melangkah di sekitar kekurangan molekul lookahead dan melihat-panjang variabel di belakang (tidak perlu menarik teknik canggih yang sebelumnya digunakan), dan 64 byte lebih pendek! Selain itu menghilangkan kompleksitas memperlakukan N bebas dan N prima sebagai kasus khusus yang berbeda, menjatuhkan 7 byte lain dari solusi ini.
(Masih ada masalah lain yang memerlukan teknik canggih yang sebelumnya digunakan di sini untuk mengurangi perhitungan Q, tetapi saat ini tidak satupun dari mereka yang diwakili oleh posting PPCG saya.)
Saya menempatkan tes multiplisitas sebelum tes bilangan prima berturut-turut karena yang terakhir jauh lebih lambat; melakukan tes yang dapat gagal lebih cepat terlebih dahulu membuat regex lebih cepat untuk input yang didistribusikan secara merata. Golf juga lebih baik untuk didahulukan, karena menggunakan lebih banyak referensi (yang akan lebih mahal jika dua digit).
Saya dapat menjatuhkan 4 byte dari regex ini (193 → 189) menggunakan trik yang ditemukan oleh Grimy yang dapat memperpendek pembagian dalam kasus bahwa hasil bagi dijamin lebih besar dari atau sama dengan pembagi.
^(?=(|(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?)$))
Cobalah online!
# 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?)$
)
)
* Masih lebih bersih dengan lookahead molekuler, tanpa kasus khusus untuk N yang bebas persegi. Ini turun 6 byte, menghasilkan solusi 195 187 183 byte :
^(?=(?*(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?)$
)
)
Ini porting ke tampilan panjang variabel:
Regex (ECMAScript 2018), 198 195 194 186 182 byte
^(?=(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+))))
Cobalah online!
# 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
)