我知道这个问题已经被问到,但是我很难找到为什么我得到了错误的答案,其他关于这个的帖子对我没有帮助。代码是找到低于2,000,000的素数之和。
import math
import numpy as np
def sum_primes(limit):
potential = 2
primes = [potential]
potential += 1
primes.append(potential)
while potential < limit:
potential+=2
test = True
sqrt_potential = math.sqrt(potential)
for a in primes:
if a > sqrt_potential:
break
if potential%a == 0:
test = False
break
if test and potential <= limit:
primes.append(potential)
print np.sum(primes)
return
看来我正在击中所有素数,但由于某种原因,总和还没有正确出现。有人在这看到问题吗?
以下是我得到的一些输出:
>>> sum_primes(20000)
21171191
>>> sum_primes(200000)
1709600813
>>> sum_primes(2000000)
1179908154
答案 0 :(得分:2)
在脚本的初始化部分,设置potential = 3
。然后while循环中的第一个语句将potential增加到5.您永远不会将3视为潜在素数。通过在脚本的初始化部分设置potential -= 1
来修复它。
更好的算法使用了Eratosthenes的Sieve:
def sumPrimes(n):
b, p, sum = [True] * (n+1), 2, 0
for p in xrange(2, n+1):
if b[p]:
sum += p
for i in xrange(p, n+1, p):
b[i] = False
return sum
如果您要在Project Euler中执行素数问题,您可能需要在我的博客上阅读Programming with Prime Numbers。
答案 1 :(得分:2)
我给出了一个相当天真的实现,最后一次迭代需要一段时间才能返回结果。
def return_primes(upto=100):
primes = []
for i in range(2, upto+1):
if not any(not i % p for p in primes):
primes.append(i)
return primes
用法:
>>> sum(return_primes(upto=20000))
21171191
>>> sum(return_primes(upto=200000))
1709600813
>>> sum(return_primes(upto=2000000))
142913828922
这是使用Sieve of Eratosthenes的另一个实现:
def return_primes(upto=100):
primes = []
sieve = set()
for i in range(2, upto+1):
if i not in sieve:
primes.append(i)
sieve.update(range(i, upto+1, i))
return primes
这比更多更快,在大约一两秒内运行,而上述时间则为几分钟:
>>> sum(return_primes(200000))
1709600813
>>> sum(return_primes(2000000))
142913828922
要尝试使用此信息更好地诊断您的问题,我们会看到
>>> 142913828922 % 2**32
1179908154
哪位(谢谢Will Ness)让人得出结论,你用32位整数求和。如果我们将您的代码更改为以下内容:
import math
import numpy as np
def sum_primes(limit):
potential = 2
primes = [potential]
potential += 1
primes.append(potential)
while potential < limit:
potential+=2
test = True
sqrt_potential = math.sqrt(potential)
for a in primes:
if a > sqrt_potential:
break
if potential%a == 0:
test = False
break
if test and potential <= limit:
primes.append(potential)
print np.sum(primes, dtype=np.int64)
return
然后你应该得到正确的输出。
如果我改用你的行为,我会复制你的行为:
print np.sum(primes, dtype=np.int32)