Regex (ECMAScript), 276 205 201 193 189 байт
Сравнение кратностей (показателей степени) различных простых факторов представляет собой интересную проблему для решения с помощью регулярного выражения ECMAScript - отсутствие обратных ссылок, сохраняющихся в течение итераций цикла, затрудняет подсчет чего-либо. Даже если подсчет рассматриваемой числовой черты возможен, часто более косвенный подход делает гольф лучше.
Как и в других моих статьях по регулярному выражению в ECMA, я дам предупреждение: я настоятельно рекомендую научиться решать унарные математические задачи в регулярном выражении в ECMAScript. Для меня это было увлекательное путешествие, и я не хочу испортить его тем, кто потенциально может попробовать его сами, особенно тем, кто интересуется теорией чисел. См. Этот более ранний пост для списка последовательно рекомендованных спойлером рекомендованных проблем, чтобы решить одну за другой.
Так что не читайте дальше, если вы не хотите, чтобы какая-то продвинутая магия унарных регулярных выражений была испорчена для вас . Если вы действительно хотите сами разобраться в этой магии, я настоятельно рекомендую начать с решения некоторых проблем в регулярном выражении ECMAScript, как описано в этом посте, связанном выше.
Основная полезная нагрузка от ранее разработанного мной регулярного выражения оказалась очень подходящей для этой задачи. Это регулярное выражение, которое находит простые числа наибольшей кратности . Мое первое решение для этого было очень долгим, и позже я постепенно продвинулся вперед, сначала переписав его, чтобы использовать молекулярный взгляд , а затем перенес его обратно на простой ECMAScript, используя продвинутую технику, чтобы обойти отсутствие молекулярного взгляда , и впоследствии игра в гольф будет намного меньше, чем оригинальное простое решение ECMAScript.
Часть из этого регулярного выражения, которая относится к этой проблеме, является первым шагом, который находит Q, наименьший фактор из N, который разделяет все его основные факторы. Как только мы получим это число, все, что нам нужно сделать, чтобы показать, что N - «число с постоянной экспонентой», - это делить N на Q, пока мы не сможем больше; если результат равен 1, все простые числа имеют одинаковую кратность.
Отправив ответ, используя мой ранее разработанный алгоритм поиска Q, я понял, что его можно рассчитать совершенно по-другому: найти наибольший множитель без квадратов для N (используя тот же алгоритм, что и для регулярного выражения моего числа Кармайкла ). Как выясняется, это вовсе не представляет никаких трудностей * с точки зрения обхода отсутствия молекулярного предвзятого взгляда и заднего вида переменной длины (нет необходимости использовать продвинутый ранее метод) и на 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
)