Why is this Haskell expression so slow?

后端 未结 3 1410
自闭症患者
自闭症患者 2020-12-31 16:46

I\'m working on Project Euler Problem 14. Here\'s my solution.

import Data.List

collatzLength :: Int->Int
collatzLength 1 = 1
collatzLength n | odd n = 1         


        
相关标签:
3条回答
  • 2020-12-31 17:19

    You're assuming that the collatzLength function will be memoized. Haskell does not do automatic memoization. You'll need to do that yourself. Here's an example using the data-memocombinators package.

    import Data.List
    import Data.Ord
    import qualified Data.MemoCombinators as Memo
    
    collatzLength :: Integer -> Integer
    collatzLength = Memo.arrayRange (1,1000000) collatzLength'
      where
        collatzLength' 1 = 1
        collatzLength' n | odd n  = 1 + collatzLength (3 * n + 1)
                         | even n = 1 + collatzLength (n `quot` 2)
    
    main = print $ foldl1' max $ [(collatzLength n, n) | n <- [1..1000000]]
    

    This runs in about 1 second when compiled with -O2.

    0 讨论(0)
  • 2020-12-31 17:19

    cL is short for collatzLength

    cL!!n stands for collatzLength n

    cL :: [Int]
    cL = 1 : 1 : [ 1 + (if odd n then cL!!(3*n+1) else cL!!(n `div` 2)) | n <- [2..]]
    

    Simple test:

    ghci> cL !! 13
    10
    
    0 讨论(0)
  • 2020-12-31 17:32

    For being able to find a maximum of a list, the whole list needs to be evaluated.

    So it will calculate collatzLength from 1 to 1000000 and collatzLength is recursive. The worst thing is, that your definition of collatzLength is even not tail-recursive.

    0 讨论(0)
提交回复
热议问题