项目euler#5的代码不起作用

时间:2017-12-27 06:00:47

标签: python

项目欧拉#5的问题是: 2520是可以除以1到10中的每个数字而没有任何余数的最小数字。 可以被1到20的所有数字整除的最小正数是多少?

result=1
done=False
while not done:
    result+=1
    for x in range(2,21):
        if result%x!=0:
            break
        elif x==20:
            done=True
print(result)

但运行时需要很长时间。好吧,似乎这段代码不起作用。这段代码有什么问题?

2 个答案:

答案 0 :(得分:1)

您正在寻找的是数字1到20中被称为“最不常见的多个"或者LCM”的内容。这是多个数字的结合这些数字的主要因素。例如,12和15的最小公倍数是多组{2,2,3}和{3,5}的并集,即{2,2,3,5}或60。

如果你有GCD功能("最大公约数"),那么你可以利用LCM(x,y)= x * y // GCD(x,y)的事实。然后,您可以从1开始累积LCM,并依次添加每个数字的唯一因子。

如果你正在使用Python 3,那么你可以从math.gcd获得GCD。例如,以下将给出1到10的答案:

import math
r = 1
for i in range(2, 11):
    r = r * i // math.gcd(r, i)

print(r)

这会按预期提供2520。对于1到20,只需:

import math
r = 1
for i in range(2, 21):
    r = r * i // math.gcd(r, i)

print(r)

这会给232792560

两种计算基本上都是即时的。

更新:你可以通过用以下代码替换循环体来实际挤出更多的东西:

    r *= i // math.gcd(r, i)

这是有效的,因为imath.gcd(r, i)的倍数。通过在乘法之前进行除法,计算中涉及的数字会略小一些。

答案 1 :(得分:0)

因为它必须除以20,因此您只能检查20的倍数 - 这样您就必须检查更少的数字。

如果数字除以20,则必须除以21020=2*10),4520=4*5),因此您无需检查24510。同样可以消除其他数字。

最后我得到了列表20191817161514,{ {1}},13

11

结果:

import time

start = time.time()

result = 0
done = False

while not done:
    result += 20
    for x in [20, 19, 18, 17, 16, 15, 14, 13, 11]:
        if result % x != 0:
            break
    else:
       done = True

end = time.time()

print('result:', result)
print('time in seconds:', end-start)