我试图用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")
如何使我的程序更高效?
答案 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)