【发布时间】:2011-07-04 23:04:34
【问题描述】:
我有一个工作程序来计算给定范围内最长的 collatz 链(项目 euler n°14)。我认为它可以正常工作,但速度很慢。我试图寻找更好的解决方案,但我只能稍微减少评估域。我做错了吗?
该实现使用记忆化来避免两次计算相同的结果。 Data.Map 对一般性能不利吗?
import Data.Map ((!), member, insert, singleton, assocs, Map)
insertSolution::Integer->(Map Integer Integer)->(Map Integer Integer)
insertSolution n syracMap
| n `member` syracMap = syracMap
|otherwise = let
next = if n `mod` 2 == 0 then n `div` 2 else 3 * n + 1
newMap = insertSolution next syracMap
solution = newMap ! next + 1
in insert n solution newMap
bound = 1::Integer
lower = 999999::Integer
test::[Integer]
test = [lower,lower+2..bound]
values = takeWhile (\(k, v) -> k < bound) $ assocs $ foldr insertSolution (singleton 1 1) test
result = foldr (\(k, v) (k', v') -> if v > v' then (k, v) else (k', v')) (1, 1) values
main = putStr $ show $ result
编辑
更新功能以消除错误。我的笔记本电脑还是很慢。
【问题讨论】:
-
我可以看到的一个问题是您正在递归调用
insertSolution(在您的变量newMap),但在旧地图而不是更新地图上。这不允许共享。不知道是不是故意的。 -
不,不是。我将测试新版本。谢谢你的评论。
-
我最近开始使用 data-memocombinators 进行我的 Project Euler 尝试。您可能想尝试一下...
标签: performance haskell