优化eulerproject解决方案5 - 最小倍数

时间:2017-07-18 19:36:50

标签: python optimization

如何优化代码?我花了大约3分钟才终于得到了答案。

这是代码:

def myfunc():
    smallest = 0;
    while True:
        smallest +=1
        for x in range(1, 21):
            if smallest % x != 0:
                break
            else:
                if x == 20:
                    print(smallest)
                    return
myfunc()

谢谢:)

2 个答案:

答案 0 :(得分:1)

您可以简单地生成从1到(包括)20的所有元素的最小公倍数

三个(或更多数字)lmc(a,b,c) == lmc(lmc(a,b),c)的最小公倍数(lcm)。

现在为了计算最小公倍数,我们可以使用欧几里得算法计算最大公约数(gcd):

def gcd(x,y):
    while y != 0:
        x, y = y, x % y
    return x

现在我们可以用lcm

来定义gcd
def lcm(x,y):
    return x*y//gcd(x,y)

然后让它适用于列表:

def lcm_list(x,*args):
    for y in args:
        x = lcm(x,y)
    return x

所以现在我们可以计算它:

lcm_list(*range(1,21))

这会产生:

>>> lcm_list(*range(1,21))
232792560

并且它可以被1到20之间的每个数字整除:

>>> [232792560%i for i in range(1,21)]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

答案 1 :(得分:-1)

这个问题可以通过分析解决。无需编程。

逻辑如下:如果n除以数字k,则它还会除k * m。因此,我们正在寻找的数字是所有数字n的乘积,它可以被写为集合中任何较小数字的乘积。

这些数字中没有一个可以是非素数幂复合数,因为否则它是集合中已有的较小数的乘积,但另一方面它必须包含小于20的所有素数幂,因为这些不是集合中任何较小数字的乘积。既然我们知道素数(通过心脏,或参考一些列表/写一个函数),我们现在有了解决方案。

因此我的代码将是

>>> (2 ** 4) * (3 ** 2) * 5 * 7 * 11 * 13 * 17 * 19
232792560