Regex (ECMAScript), 276 205 201 193 189 байт
Порівнювання множинності (експонентів) різних простих факторів є цікавою проблемою для вирішення за допомогою регулярного виразів ECMAScript - відсутність зворотних посилань, що зберігаються через ітерації циклу, стає завданням рахувати що завгодно. Навіть якщо підрахунок відповідної числової ознаки є можливим, часто більш опосередкований підхід сприяє кращому гольфу.
Як і в інших моїх регламентах ECMA, я попереджую спойлер: я настійно рекомендую навчитися вирішувати одинакові математичні задачі в регулярному виразі ECMAScript. Це була захоплююча подорож для мене, і я не хочу її зіпсувати нікому, хто, можливо, захоче спробувати його сам, особливо тим, хто цікавиться теорією чисел. Перегляньте це попереднє повідомлення, щоб ознайомитися зі списком рекомендованих послідовно позначених спойлерами проблем, які потрібно вирішити по черзі.
Тож не читайте більше, якщо ви не хочете, щоб якась просунута онірна регекс-магія зіпсована для вас . Якщо ви дійсно хочете зняти цю магію самостійно, я настійно рекомендую почати з вирішення деяких проблем у регулярному вираженні ECMAScript, як описано у цій публікації, що пов’язана вище.
Основна корисна навантаження з попередньо розробленого я регулярного виразу виявилася дуже застосовною для цього завдання. Це саме регулярний вираз, який знаходить прайм (и) найбільшої кратності . Моє перше рішення для цього було дуже довгим, і я пізніше гольфував його поетапно, спочатку переписав його на використання молекулярного пошуку , а потім переніс його на звичайний ECMAScript, використовуючи вдосконалену техніку, щоб подолати відсутність молекулярного пошуку , а згодом гольф вниз, щоб бути набагато меншим, ніж оригінальне звичайне рішення ECMAScript.
Частина цього регексу, що застосовується до цієї проблеми, є першим кроком, який знаходить Q, найменший фактор N, що ділиться на всі його основні фактори. Після того, як ми отримаємо це число, все, що нам потрібно зробити, щоб показати, що N - число "постійного показника", - це ділити N на Q, поки ми не зможемо більше; якщо результат дорівнює 1, всі прайми мають однакову кратність.
Подавши відповідь, використовуючи попередньо розроблений алгоритм пошуку Q, я зрозумів, що його можна обчислити зовсім по-іншому: Знайдіть найбільший квадратний вільний коефіцієнт N (використовуючи той самий алгоритм, що і мій регекс числа Carmichael ). Як виявляється, це зовсім не створює труднощів * з точки зору подолання нестачі молекулярної розвідки та змінної довжини позаду (не потрібно застосовувати вдосконалену раніше техніку), і на 64 байти коротше! Крім того, це виключає складність трактування N без прямокутника і простого N як різних спеціальних випадків, видаляючи з цього рішення ще 7 байт.
(Досі залишаються інші проблеми, для яких потрібна вдосконалена техніка, яка раніше використовувалася для гольфу для обчислення Q, але наразі жодна з них не представлена моїми повідомленнями про PPCG.)
Я ставлю тест на кратність перед тестом послідовних праймес, оскільки останній значно повільніше; введення тестів, які можуть вийти з ладу швидше, спочатку робить регекс швидше для рівномірного розподілу введення. Також гольф краще поставити на перше місце, тому що він використовує більше зворотних посилань (що коштувало б дорожче, якби вони були двозначними).
Мені вдалося скинути 4 байти з цього регулярного виразу (193 → 189) за допомогою трюку, знайденого Гримі, який може в подальшому скоротити поділ у випадку, якщо коефіцієнт гарантовано буде більшим або рівним дільнику.
^(?=(|(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?)$))
Спробуйте в Інтернеті!
# 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, що не має площі. Це падає 6 байт, даючи 195 187 183 байт розчин:
^(?=(?*(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?)$
)
)
Ось воно переноситься на змінну довжину позаду:
Regex (ECMAScript 2018), 198 195 194 186 182 байт
^(?=(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+))))
Спробуйте в Інтернеті!
# 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
)