2014-01-29 59 views
0

这是我对Project Euler中第5个问题的解决方案。有没有什么办法可以改善while循环而不是使用总和?优化Project Euler#5的Python代码

table = range(1,21) 
result = 1 
pf = 2 
while sum(table) > len(table): 
    flag = False 
    for x,y in enumerate(table): 
     if y % pf == 0: 
     table[x] = y/pf 
     flag = True 
    if flag: 
     result *= pf 
    else: 
     pf += 1 
print result 
+6

这个问题似乎是题外话,因为它属于在http://codereview.stackexchange .com – jonrsharpe

回答

3

它总是清晰的编写使用一个循环的高阶函数,而不是因为所有的控制环的操作无关变量的消失的程序。下面是执行相同的计算为你的程序,但whilefor圈消失,因为这样做的变量tableresultpfflag;变量xy依然存在,但仅限于辅助功能,而不是作为主要的计算的一部分提供支撑作用:

>>> from fractions import gcd 
>>> def lcm(x,y): return x*y/gcd(x,y) 
... 
>>> print reduce(lcm,range(1,21)) 
232792560 
+0

我不同意它总是更清晰 - 您总是需要考虑是否通过将循环转换为函数来使代码更易读。 –

+0

@SimeonVisser:当然任何事情都可以被滥用。但隐藏管道使大多数程序更清晰和简单。 – user448810

1

使用常数。当你想回去尝试不同的价值时,理解起来会更容易。

MAX_DIVISOR = 20 
table = range(1,MAX_DIVISOR + 1) 
result = 1 
pf = 2 
while pf < MAX_DIVISOR + 1: 
    flag = False 
    for x,y in enumerate(table): 
     if y % pf == 0: 
    table[x] = y/pf 
    flag = True 
    if flag: 
     result *= pf 
    else: 
     pf += 1 
print result 
+0

这个条件是如何工作的? pf是我用来分解表中元素的主要因素,如果它是他们的因素。当表中的所有项都是1时,算法停止。我不明白为什么pf必须小于表中的最大元素。那么我做,但它是如何有意义的循环条件? – Veritas

+0

修复了while循环条件中的错误。如果你在查看'table'的内容的时候看到它会继续增加'pf'直到达到19 - 最后一个素数。实际上,您的版本将始终保持工作状态,直到达到目标编号之前的最后一个素数。 – JoeClacks

+0

此版本(带有固定条件)只运行到最后一个数字。所以唯一的区别就是在[OO((ln(n))^ 2)左右运行的[Pri​​me gap](http://en.wikipedia.org/wiki/Prime_gap)** - 大多是微不足道的。事实上,如果我们想使这个算法明显更好,我们可以将'pf'设置为素数序列 - 避免测试任何复合数字。 – JoeClacks

0

你可以使用any()测试表,就像这样:

while any(n != 1 for n in table): 
    # do stuff 

我觉得这是比sum(table) > len(table)清晰。

另外,正如@JoeClacks推荐的那样,使用一个常量。

完成修订方案:

MAX_DIVISOR = 20 
table = list(range(1, MAX_DIVISOR+1)) 

result = 1 
pf = 2 

while any(n != 1 for n in table): 
    assert pf <= MAX_DIVISOR 
    flag = False 
    for i,n in enumerate(table): 
     if n % pf == 0: 
      table[i] = n//pf 
      flag = True 
    if flag: 
     result *= pf 
    else: 
     pf += 1 

print(result) 

我添加了一个assert确保pf只有合法值;只要代码中没有错误,就不需要这样做,但对代码进行自我检查可能是一个好主意。

我用in用于索引和数目,而不是xy

我使用Python的整数除法运算符//而不是/,因此代码在Python 3.x上的工作方式与在Python 2.x上的工作方式相同。另外,我写了print声明的方式在Python 3.x和Python 2.x中同样适用。

我改变了缩进的4个空格步骤按照PEP 8

http://www.python.org/dev/peps/pep-0008/

注:我很喜欢这个算法,解决这个问题。它很优雅。你是否创造了这个,从书中得到它,或者是什么?

编辑:其实,项目欧拉问题5已经在StackOverflow这里讨论过。这是一个答案,我只是比较上述答案。这个比上面几乎快十倍。这有点棘手,但!

https://stackoverflow.com/a/8026041/166949

+0

算法昨天刚刚发生,但它可能已经存在。顺便说一句,任何函数表达的条件比我使用的总和要好得多。我想到的是用一个有条件的主要因素取而代之,但我甚至不确定这是否可能。 – Veritas