正規表現(のECMAScript)、276の 205 201 193 189バイト
さまざまな素因数の多重度(指数)を比較することは、ECMAScript正規表現で解決するための興味深い問題です。ループの反復を通じて持続する後方参照がないため、何を数えるのも困難です。問題の数値特性を数えることができたとしても、多くの場合、より間接的なアプローチはより良いゴルフになります。
私の他のECMA正規表現の投稿と同様に、ネタバレ警告を出します。ECMAScript正規表現の単項数学問題を解決する方法を学ぶことを強くお勧めします。それは私にとって魅力的な旅であり、自分で試してみたいと思う人、特に数論に興味のある人のためにそれを台無しにしたくありません。1つ1つ解決するための連続したスポイラータグ付きの推奨される問題のリストについては、この以前の投稿を参照してください。
したがって、高度な単項正規表現の魔法を台無しにしたくない場合は、これ以上読んではいけません。この魔法を自分で理解するためにショットを撮りたい場合は、上記のリンクに記載されているECMAScript正規表現の問題を解決することから始めることを強くお勧めします。
私が以前に開発した正規表現の主なペイロードは、この課題に非常に適用できることが判明しました。それが最高の多重度の素数を見つける正規表現です。私の最初の解決策は非常に長く、後に段階的にゴルフを進め、最初に分子先読みを使用するように書き直し、次に分子先読みの欠如を回避する高度な技術を使用してプレーンECMAScriptに移植し、その後元のプレーンなECMAScriptソリューションよりもはるかに小さくなるように、それをゴルファーします。
この問題に適用される正規表現からの部分は、最初のステップで、すべての素因数を共有するNの最小要素であるQを見つけます。この数を取得したら、Nが「定数指数」であることを示すために必要なことは、それ以上できなくなるまでNをQで除算することです。結果が1の場合、すべての素数の多重度は等しくなります。
Qを見つけるために以前に開発したアルゴリズムを使用して回答を送信した後、まったく異なる方法で計算できることに気づきました:Nの最大の平方フリーファクターを見つける(私のCarmichael数値正規表現と同じアルゴリズムを使用)。結局のところ、これは分子の先読みと可変長の先読みの欠如を回避するという点でまったく困難ではありません*(以前に使用された高度な技術を取り入れる必要はありません)。さらに、平方フリーNと素数Nを異なる特殊なケースとして扱う複雑さを排除し、このソリューションからさらに7バイトを削除します。
(Qを計算するためにここで以前使用された高度な技術を必要とする他の問題がまだ残っていますが、現在それらのどれも私のPPCG投稿によって表されません。)
連続プライムテストの方がずっと遅いため、多重プライムテストを連続プライムテストの前に配置しました。より早く失敗する可能性のあるテストを最初に配置すると、均一に分散された入力の正規表現が高速になります。また、より多くの後方参照を使用するため(2桁の場合はコストが高くなります)、最初に置く方が良いでしょう。
私はで見つかったトリックを使用して(193→189)、この正規表現から4つのバイトを削除することができた汚れた商がより大きい又は除数に等しくなることが保証されている場合には短く分割futherできます。
^(?=(|(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?)$
)
)
ここでは、可変長の後読みに移植されています。
正規表現(ECMAスクリプト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
)