欧拉23号项目效率

时间:2018-08-23 14:45:52

标签: python python-3.x performance processing-efficiency

我试图用python编写程序来回答以下问题:

  

一个完美数是一个数字,它的适当除数之和等于该数字。例如,适当除数为28的总和将为1 + 2 + 4 + 7 + 14 = 28,这意味着28是一个完美数。
   如果数字n的适当除数之和小于n,则称该数字为不足    大于n,并且如果总和超过n,则称为丰富。
   由于12是最小的丰富数,所以1 + 2 + 3 + 4 + 6 = 16,可以写成两个丰富的数之和的最小数是24。
  通过数学分析,可以证明所有大于28123的整数都可以写为两个丰富数字的总和。但是,即使已知无法表示为两个丰富数字之和的最大数字小于该上限,也无法通过分析进一步减小该上限。
  找到所有不能写为两个丰富数字之和的正整数之和。

所以这是我的代码,理论上应该可以运行,但是速度太慢了。

import math
import time

l = 28123

abondant = []
def listNumbers():
        for i in range(1, l):
            s = 0
            for k in range(1, int(i / 2) + 1):
                if i % k == 0:
                    s += k
            if s > i:
                abondant.append(i)

def check(nb):
    for a in abondant:
        for b in abondant:
            if a + b == nb:
                return False
    return True

def main():
    abondant_sum = 0
    for i in range(12, l):
        if check(i):
            abondant_sum += i
    return abondant_sum

start = time.time()
listNumbers()
print(main())
end = time.time()
print("le programme a mis ", end - start, " ms")

如何使我的程序更高效?

3 个答案:

答案 0 :(得分:2)

只检查一半并将所有通过的数字相加是非常低效的。
尝试改变

        for k in range(1, int(i / 2) + 1):
            if i % k == 0:
                s += k

        for k in range(1, int(i**0.5)+1):
            if i % k == 0:
                s += k
                if k != i//k:
                    s += i//k

答案 1 :(得分:1)

一旦有了大量数字的列表,就可以创建一个列表git rebase -i,然后

result = [False] * 28123

然后

for a in abondant:
    for b in abondant:
        result[min(a+b, 28123)] = True

答案 2 :(得分:1)

问题是您在调用28111次的check函数中对“助手”进行了两次迭代。 仅计算一次所有a + b的集合,然后检查您的数字是否在内部,效率会更高。

类似的东西:

def get_combinations():
    return set(a+b for a in abondant for b in abondant)

然后可能是主要功能:

def main():
    combinations = get_combinations()
    non_abondant = filter(lambda nb: nb not in combinations, range(12,l))
    return sum(non_abondant)