欧拉项目的解决方案任务5:为什么它有效?

时间:2016-06-20 11:53:47

标签: python optimization

经过一些反复试验后,我找到了一个适用于Project Euler Problem 5的解决方案。 (我找到了另一种正确解决了案例(数字1-10)的方法,但是花了很长时间来解决实际的问题。)这就是:

def test(n):
    for x in range(2,21):
        if n % x != 0:
            return False
    return True

def thwart(n):
    for x in range(2,21):
        if test(n/x):
            n /= x
            return n
    raise TypeError

num = 1
for x in range(1,21):
    num *= x

while True:
    try:
        num = thwart(num)
    except TypeError:
        break


print(num)

我的主要问题是理解为什么反复调用thwart(num)足以导致正确的解决方案。 (即,为什么它能够找到最小的数字并且不会吐出任何可被数字1-20整除的数字?) 编程时我只有一些模糊的想法,并对它的工作速度感到惊讶。但是现在我很难弄清楚为什么它甚至可以正常工作......到目前为止我发现的其他人的优化解决方案都在讨论我无法看到的那些适合我的程序的主要因素......? 任何帮助表示赞赏!谢谢!

1 个答案:

答案 0 :(得分:1)

这不是一个编码问题,而是一个数学问题。如果您查看1-20中的所有数字作为主要内容,您将获得以下内容: 1,2,3,2 ^ 2,5,2 ^ 3,7,2 ^ 3 .... 2 ^ 2 * 5。 这里有趣的部分是,一旦你乘以这些数字中每个因子的最高指数,你将得到一个数字,可以除以1到20之间的每个数字。 一旦你意识到这个问题是一个简单的数学问题并且接近它就可以使用这个基本代码:

import math
primes = [2]
for n in range(3,21): #get primes between 1 and 20
    for i in primes:
        if n in primes:
            break
        if n%i == 0:
            break
        if i> math.sqrt(n):
            primes.append(n)
            break
s = 1
for i in primes:
    for j in range(10): # no reason for 10, could as well be 5 because 2^5 >20
        if i**j > 20:
            s = s*(i**(j-1))
            break

print s

此外,提示数字2520是可以除以所有数字的最小数字应该让您了解如何选择2520: 我为你拍了一张照片: enter image description here 正如你可以计算的那样,当你拿走最大的指数并乘以它们时,得到数字2520。

您的解决方案 你的解决方案基本上取1 * 2 * 3 * 4 .. * 20的数字,然后尝试将它除以2到20之间的每个数字,使它仍然保持相关性。通过一遍又一遍地运行它,从中删除不需要的数字。在它的早期将删除所有不必要的2,除以2,返回数字,然后再次调用再次除以2。一旦所有的两个被淘汰,它将消除所有三分球,一旦所有不必要的三分球将被淘汰,它将尝试除以4并且它将不会工作,继续到5,6,7 ......并且当它结束时循环不能分割它会引发TypeError,你将用正确的数字完成你的程序。这不是解决此问题的有效方法,但它可以使用少量数据。