2014-01-29 56 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