代码无法使用较大的列表

时间:2017-07-05 08:43:25

标签: python math primes

我正在编写项目euler的问题。问题50 https://projecteuler.net/problem=50

问题是我的代码适用于小型列表,特别是几千个以下的素数列表,但是,它无法使用低于100万的素数列表(约为80000个素数)这是一个问题得到答案。

有两个主要问题:

  1. 大大超过20000(10 - 20分钟)的大型名单非常缓慢
  2. 它没有产生正确的答案
  3. 即使逻辑正确并且运行完毕,答案也是错误的,这是一个内存问题吗?我想知道为什么我的代码只适用于较小的数据以及如何提高效率

    另外,如果我问一个不好的问题,请告诉我。

    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)
    

2 个答案:

答案 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

但根据您的计算机,这可能还需要一分多钟。这是因为你首先通过移动xy来测试两个素数的所有和,然后测试三个素数的所有和,然后增加两者之间的差异。

相反,如果你转过来,首先看一下许多小素数的总和,而不是几个大素数的总和,你会很快找到结果 - 从第三个素数开始!

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
  • 我使用了一个集来检查它是否在,因为集合有固定的时间搜索
  • 我停止了迭代,如果不可能有更长的设置,但没有超过最大的寻找素数
  • 我使用了enumerateaccumulateislice的一些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...