我正在编写项目euler的问题。问题50 https://projecteuler.net/problem=50
问题是我的代码适用于小型列表,特别是几千个以下的素数列表,但是,它无法使用低于100万的素数列表(约为80000个素数)这是一个问题得到答案。
有两个主要问题:
即使逻辑正确并且运行完毕,答案也是错误的,这是一个内存问题吗?我想知道为什么我的代码只适用于较小的数据以及如何提高效率
另外,如果我问一个不好的问题,请告诉我。
def primes(n):
sieve = [True] * n
for i in range(3,int(n**0.5) + 1, 2):
if sieve[i]:
sieve[i * i :: 2 * i] = [False] * int((n - i * i - 1)/(2 * i) + 1)
return [2] + [i for i in range(3, n, 2) if sieve[i]]
primes = primes(1000)
start = 0
answer = 0
x = 0
count = y = 2
while len(primes[x:y - 1]) < len(primes):
summed = sum(primes[x:y])
length = len(primes[x:y])
if summed in primes and length > start:
start = length
answer = summed
x += 1
y += 1
if y - 1 == len(primes):
count += 1
x = 0
y = count
print(start)
print(answer)
答案 0 :(得分:0)
正如评论中所述,您的代码中存在一些不必要的线性复杂性,例如:用于确定当前总和中的元素数量,或者该数量是否在素数列表中。如果你消除了这些,你的算法会变得更快。
p_set = set(primes) # use a set for lookup
summed = None
while y - 1 - x < len(primes):
# instead of getting the sublist and the sum, just update the last sum
summed = sum(primes[x:y]) if summed is None else summed - primes[x-1] + primes[y-1]
length = y - x # no need for creating the sublist
if summed in p_set and length > start: # lookup in set
start = length
answer = summed
print(start, answer)
x += 1
y += 1
if y - 1 == len(primes):
count += 1
x = 0
y = count
summed = None # reset sum
但根据您的计算机,这可能还需要一分多钟。这是因为你首先通过移动x
和y
来测试两个素数的所有和,然后测试三个素数的所有和,然后增加两者之间的差异。
相反,如果你转过来,首先看一下许多小素数的总和,而不是几个大素数的总和,你会很快找到结果 - 从第三个素数开始!
max_ = res = 0
for i in range(len(primes)):
sum_ = primes[i]
for k in range(i+1, len(primes)):
sum_ += primes[k]
if sum_ in p_set and k - (i - 1) > max_:
max_, res = k - (i - 1), sum_
print(max_, res, i, k)
if sum_ > MAX:
break
答案 1 :(得分:0)
我采取了另一种方法
我从素数列表中的每个元素检查是否存在连续序列,长于直到那时总和为素数的最长序列
import itertools
def primes(n):
found_primes = [True] * (n + 1)
for i in range(2, n + 1):
if found_primes[i]:
yield i
for j in itertools.takewhile(lambda x: x * i <= n, itertools.count(1)):
found_primes[j * i] = False
def find_longer_consecutive_sums(elements):
n = len(elements)
elements_set = set(elements)
max_elements = 1
max_prime = elements[-1]
for i in range(len(elements) - 1):
if sum(elements[i: i + max_elements]) > max_prime:
return
for j, k in enumerate(itertools.islice(itertools.accumulate(elements[i:]), max_elements, len(elements)), max_elements + 1):
if k in elements_set:
max_elements = j
yield i, j, k
enumerate
,accumulate
和islice
的一些itertools魔法来:
itertools.islice(x, max_elements, len(elements))
itertools.accumulate(elements[i:])
primes_list = list(primes(1000000))
results_longer = {}
for i, j, k in find_longer_consecutive_sums(primes_list):
selected_primes = primes_list[i:i+j]
print(i, j, k, sum(selected_primes), selected_primes)
results_longer[(j, i, k)] = selected_primes
稍微超过一秒钟返回:
0 2 5 5 [2, 3]
0 4 17 17 [2, 3, 5, 7]
0 6 41 41 [2, 3, 5, 7, 11, 13]
0 12 197 197 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, ...
0 14 281 281 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, ...
0 60 7699 7699 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31...
0 64 8893 8893 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31...
0 96 22039 22039 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ...
0 100 24133 24133 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 102 25237 25237 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 108 28697 28697 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 114 32353 32353 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 122 37561 37561 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 124 38921 38921 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 130 43201 43201 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 132 44683 44683 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 146 55837 55837 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 152 61027 61027 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 158 66463 66463 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 162 70241 70241 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 178 86453 86453 [2, 3, 5, 7, 11, 13, 17, 19, 23, 29,...
0 192 102001 102001 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 198 109147 109147 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 204 116533 116533 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 206 119069 119069 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 208 121631 121631 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 214 129419 129419 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 216 132059 132059 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 296 263171 263171 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 308 287137 287137 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 326 325019 325019 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 328 329401 329401 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 330 333821 333821 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 332 338279 338279 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 334 342761 342761 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 342 360979 360979 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 350 379667 379667 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 356 393961 393961 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 358 398771 398771 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 426 581921 581921 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 446 642869 642869 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 458 681257 681257 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 460 687767 687767 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 464 700897 700897 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 480 754573 754573 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 484 768373 768373 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 488 782263 782263 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 512 868151 868151 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 530 935507 935507 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
0 536 958577 958577 [2, 3, 5, 7, 11, 13, 17, 19, 23, 2...
2 537 970219 970219 [5, 7, 11, 13, 17, 19, 23, 29, 31,...
2 539 978037 978037 [5, 7, 11, 13, 17, 19, 23, 29, 31,...
3 543 997651 997651 [7, 11, 13, 17, 19, 23, 29, 31, 37...