我有一个工作程序来计算给定范围内最长的collatz链(项目euler n°14)。我认为它工作正常,但速度很慢。我试图寻找更好的解决方案,但我只能略微减少评估的域名。我做错了吗?
实现使用memoization来避免两次计算相同的结果。 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
修改
更新了删除bug的功能。我的笔记本电脑仍然很慢。
答案 0 :(得分:2)
FWIW,这是我的解决方案:
module Main
where
import Data.List
import Data.Ord
next_hailstone n | even n = n `div` 2
| otherwise = 3*n+1
gen_next_hailstone n
= if nh == 1
then Nothing
else Just (nh, nh)
where nh = next_hailstone n
hailstone n = unfoldr gen_next_hailstone n
hailstone_seqs = map hailstone [1..1000000]
zip_hailstone = zip [1..1000000] hailstone_seqs
max_hailstone = maximumBy (comparing (length . snd)) zip_hailstone
main = print . fst $ max_hailstone
它相对较快。如果您想要更快的速度,consult the Haskell wiki( SPOILER ALERT !!! )。