collat​​z链上的性能问题

时间:2011-07-04 23:04:35

标签: performance haskell

我有一个工作程序来计算给定范围内最长的collat​​z链(项目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的功能。我的笔记本电脑仍然很慢。

1 个答案:

答案 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 !!! )。