半素数を因数分解したい。この課題の目標は、u v NをFermatの方法で簡単に因数分解できるように2つの小さな整数uとvを見つけ、Nの因子を簡単に差し引くことです。Nuvu v NN
タスク
半 素数と正の整数kが与えられた場合、xとyを次のように定義します。Nkバツy
Y=X2-KN
X = ⌈ K N−−−√⌉
y= x2− k N
ステップ#1- kを見つけるk
まず、yが平方数(別名完全平方)になるように、最小値を見つける必要があります。ky
これにより、フェルマーの因数分解法の 1回の反復でを因数分解できます。より具体的には、これはすぐにつながります:k N
k N= (x + y√)× (x − y√)
(更新:このシーケンスは現在A316780として公開されています)
ステップ#2- kの因数分解k
次に、次のような2つの正の整数およびvを見つける必要があります。あなたはv
c u = x + √
u v = k
dはV=X- √c u = x + y√
dv = x − y√
ここで、とdはNの素因数です。cdN
概要
あなたの仕事は、入力としてを取り、uとvを任意の順序と妥当な形式で印刷または出力するプログラムまたは関数を書くことです。Nあなたはv
例
N = 199163を考えてみましょうN= 199163
ステップ1
可能な最小値は40で、次のようになります。k40
y=28232−40×199163=7969329−7966520=2809=532kN=(2823+53)×(2823−53)kN=2876
X = ⌈ (40 × 199163−−−−−−−−−−√)⌉ = 2823
y=28232−40×199163=7969329−7966520=2809=532
kN=(2823+53)×(2823−53)
kN=2876×2770
ステップ2
の正しい因数分解は、k = 4 ×です。kです。k=4×10
kN=2876×2770
kN=(719×4)×(277×10)
N=719×277
[4,10][10,4]
ルール
- 上記の2つの手順を厳密に適用する必要はありません。正しい値を見つける限り、他の方法を自由に使用できます。uv
- uvN
- 入力はセミプライムであることが保証されています。
- これはコードゴルフなので、バイト単位の最短回答が勝ちです。
- 標準的な抜け穴は禁止されています。
テストケース
N | k | Output
-----------+------+------------
143 | 1 | [ 1, 1 ]
2519 | 19 | [ 1, 19 ]
199163 | 40 | [ 4, 10 ]
660713 | 1 | [ 1, 1 ]
4690243 | 45 | [ 9, 5 ]
11755703 | 80 | [ 40, 2 ]
35021027 | 287 | [ 7, 41 ]
75450611 | 429 | [ 143, 3 ]
806373439 | 176 | [ 8, 22 ]
1355814601 | 561 | [ 17, 33 ]
3626291857 | 77 | [ 7, 11 ]
6149223463 | 255 | [ 17, 15 ]
6330897721 | 3256 | [ 74, 44 ]
実装例
fNuv
gNuvNO(1)
f = N => {
for(k = 1;; k++) {
x = Math.ceil(Math.sqrt(k * N));
y = x * x - k * N;
ySqrt = Math.round(Math.sqrt(y));
if(ySqrt * ySqrt == y) {
p = x + ySqrt;
for(u = 1;; u++) {
if(!(p % u) && !(N % (p / u))) {
v = k / u;
return [ u, v ];
}
}
}
}
}
g = (N, u, v) => {
x = Math.ceil(Math.sqrt(u * v * N));
y = x * x - u * v * N;
ySqrt = Math.round(Math.sqrt(y));
p = x + ySqrt;
q = x - ySqrt;
return [ p / u, q / v ];
}
[
143, 2519, 199163, 660713, 4690243, 11755703,
35021027, 75450611, 806373439, 1355814601,
3626291857, 6149223463, 6330897721
]
.map(N => {
[u, v] = f(N);
[c, d] = g(N, u, v);
console.log(
'N = ' + N + ', ' +
'u = ' + u + ', ' +
'v = ' + v + ', ' +
'N = ' + c + ' * ' + d
);
});
Nが実際にセミプライムになることが保証されていますか?