【发布时间】:2023-04-06 11:36:02
【问题描述】:
我在 Haskell 中一直致力于解决 Project Euler #14 一段时间,但由于某种原因,我无法使其正常工作。不久前我使用 Groovy 解决了这个问题,我想我在这里使用的方法基本相同。然而,即使只是找到前 10,000 个长度,程序运行速度也非常慢,我现在真的不知道为什么。我认为我正确使用了 memoization,但是即使 GHCI 中的数据集很小,我的内存也会用完。
这是我到目前为止的想法。
collatz = (map collatz' [0..] !!)
where collatz' n
| n == 1 = 1
| n `mod` 2 == 0 = 1 + collatz (n `div` 2)
| otherwise = 1 + collatz (3 * n + 1)
我会运行 map collatz [1..1000000] 来获得问题的答案,但 map collatz [1..10000] 给我一个内存不足错误,并且还需要几秒钟才能完成运行。
如果有人能给我一些关于这个程序的问题的见解,那就太好了!我已经尝试了很多东西,但我只是卡住了,需要帮助。
谢谢!
【问题讨论】:
-
你试过编译运行它吗?
-
我刚做了。我没有遇到
1..10000的内存不足错误,但它仍然花费了相同的时间。我确实遇到了数据集1..100000的内存不足错误,而且速度也很慢。 -
使用列表进行记忆不是解决这个问题的好选择。涉及很多索引,每个都需要 O(n) 时间。
-
您可以尝试现有的记忆库之一,例如MemoTrie。许多想法可以在 Haskell wiki 的 Memoization 页面找到。
-
另外data-memocombinators使用也很简单,你的
collatz变成collatz = integral collatz' where {- ... -}。我几乎立即得到map collatz [1..10000]的结果。
标签: haskell memoization collatz