我正在嘗試解決項目eulers第15個問題,格子路徑(http://projecteuler.net/problem=15)。優化遞歸函數性能(歐拉15:格子路徑)
我的第一次嘗試是逐行解決問題,然後取最後一行中的最後一個元素。
number_of_ways_new_line last_line = foldl calculate_values [] last_line
where
calculate_values lst x = lst ++ [(if length lst > 0 then (last lst) + x else head last_line)]
count_ways x = foldl (\ lst _ -> number_of_ways_new_line lst) (take x [1,1..]) [1..x-1]
result_15 = last $ count_ways 21
這工作,速度很快,但我認爲它真的很醜。所以,我想了一會兒,並用更地道的功能上來(請糾正我,如果我犯了這個錯誤),即sovles問題使用遞歸:
lattice :: Int -> Int -> Int
lattice 0 0 = 1
lattice x 0 = lattice (x-1) 0
lattice 0 y = lattice (y-1) 0
lattice x y
| x >= y = (lattice (x-1) y) + (lattice x (y-1))
| otherwise = (lattice y (x-1)) + (lattice (y-1) x)
這個工程很好的短號碼,但它根本不能縮放。我使用lattice 1 2
和lattice 2 1
將始終相同這一事實稍微優化了它。爲什麼這麼慢? Haskell不會記憶先前的結果,所以無論何時調用lattice 2 1
它都會記住舊的結果?
這個問題有非常簡單的組合答案。 – swish
它不會記憶以前的結果。如果你想使你的解決方案工作,你需要建立一些數組並遞歸地調用它的值。 – swish
你有沒有聽說過可靠的80列規則?你可以在這裏做。 http://www.emacswiki.org/emacs/EightyColumnRule – AJFarmar