如果你要解决项目欧拉问题,你需要一些处理质数和整数分解的函数。这里是我的谦虚图书馆,它提供了primes(n)
,is_prime(n)
和factors(n)
;重点是简单,清晰和简洁的速度为代价,虽然这些功能应为项目欧拉足够:
def primes(n):
"""
list of primes not exceeding n in ascending
order; assumes n is an integer greater than
1; uses Sieve of Eratosthenes
"""
m = (n-1) // 2
b = [True] * m
i, p, ps = 0, 3, [2]
while p*p < n:
if b[i]:
ps.append(p)
j = 2*i*i + 6*i + 3
while j < m:
b[j] = False
j = j + 2*i + 3
i += 1; p += 2
while i < m:
if b[i]:
ps.append(p)
i += 1; p += 2
return ps
def is_prime(n):
"""
False if n is provably composite, else
True if n is probably prime; assumes n
is an integer greater than 1; uses
Miller-Rabin test on prime bases < 100
"""
ps = [2,3,5,7,11,13,17,19,23,29,31,37,41,
43,47,53,59,61,67,71,73,79,83,89,97]
def is_spsp(n, a):
d, s = n-1, 0
while d%2 == 0:
d /= 2; s += 1
if pow(a,d,n) == 1:
return True
for r in xrange(s):
if pow(a, d*pow(2,r), n) == n-1:
return True
return False
if n in ps: return True
for p in ps:
if not is_spsp(n,p):
return False
return True
def factors(n):
"""
list of prime factors of n in ascending
order; assumes n is an integer, may be
positive, zero or negative; uses Pollard's
rho algorithm with Floyd's cycle finder
"""
def gcd(a,b):
while b: a, b = b, a%b
return abs(a)
def facts(n,c,fs):
f = lambda(x): (x*x+c) % n
if is_prime(n): return fs+[n]
t, h, d = 2, 2, 1
while d == 1:
t = f(t); h = f(f(h))
d = gcd(t-h, n)
if d == n:
return facts(n, c+1, fs)
if is_prime(d):
return facts(n//d, c+1, fs+[d])
return facts(n, c+1, fs)
if -1 <= n <= 1: return [n]
if n < -1: return [-1] + factors(-n)
fs = []
while n%2 == 0:
n = n//2; fs = fs+[2]
if n == 1: return fs
return sorted(facts(n,1,fs))
一旦你知道如何因素的数字,很容易计算除数的数。考虑76576500 = 2^2 * 3^2 * 5^3 * 7^1 * 11^1 * 13^1 * 17^1。忽略基数并查看指数,它们分别是2,2,3,1,1,1和1.给每个指数加1,给出3,3,4,2,2,2和2.现在乘以该列表以获得原始号码76576500的约数的个数:3 * 3 * 4 * 2 * 2 * 2 * 2 = 576这里的功能:
def numdiv(n):
fs = factors(n)
f = fs.pop(0); d = 1; x = 2
while fs:
if f == fs[0]:
x += 1
else:
d *= x; x = 2
f = fs.pop(0)
return d * x
您可以在http://codepad.org/4j8qp60u在工作中看到这些功能,并详细了解他们如何在my blog工作。我会给你解决问题12的解决方案。
http://stackoverflow.com/questions/110344/algorithm-to-calculate-the-number-of-divisors-of-a-given - 号码重复? – joni 2012-01-31 08:15:13
你可以将'a'除以你找到的除数,再试一次,然后继续。这将大大减少可能性的数量。如果我不想错过什么。 – rplnt 2012-01-31 08:16:25