素因数分解 (prime factorization)
概要
素因数分解を行うためのアルゴリズム。
ある数 \(N\) について、合成数の因数を確率的に発見する。
実装
def gcd(m, n):
while n:
m, n = n, m % n
return m
def pollard_rho(n, a, x0):
# use f(x) = x^2 + a (mod n)
f = lambda x: (x**2 + a) % n
x = y = x0
d = 1
while d == 1:
x = f(x)
y = f(f(y))
d = gcd(n, abs(x - y))
# return failure (-1) if d == n
return d if d < n else -1
# with Brent's improvement
def pollard_rho(n, a, x0):
# use f(x) = x^2 + a (mod n)
f = lambda x: (x*x + a) % n
x = y = ys = x0; r = 1; q = 1
m = 100
d = 1
while d == 1:
x = y
for i in range(r):
y = f(y)
for k in range(0, r, m):
ys = y
for i in range(min(m, r-k)):
y = f(y)
q = q * abs(x - y) % n
d = gcd(n, q)
if d != 1:
break
r <<= 1
if d == n:
while d == 1:
ys = f(ys)
d = gcd(n, abs(x - ys))
# return failure (-1) if d == n
return d if d < n else -1
print(pollard_rho(1000000009 * 1000000007, 1, 2))
# => "1000000009"
print(pollard_rho(2 * 3 * 5 * 17, 1, 2))
# => "6"
print(pollard_rho(1000000007, 1, 2))
# => "-1"