【发布时间】:2011-11-06 23:48:00
【问题描述】:
我正在处理 Project Euler (http://projecteuler.net/problem=14) 的问题 14。我正在尝试使用记忆化,以便将给定数字的序列长度保存为部分结果。为此,我正在使用 Data.MemoCombinators。下面的程序会产生堆栈溢出。
import qualified Data.MemoCombinators as Memo
sL n = seqLength n 1
seqLength = Memo.integral seqLength'
where seqLength' n sum = if (n == 1) then sum
else if (odd n) then seqLength (3*n+1) (sum+1)
else seqLength (n `div` 2) (sum+1)
p14 = snd $ maximum $ zip (map sL numbers) numbers
where numbers = [1..max]
max = 999999
堆栈溢出应该是由于 sum+1 被懒惰地评估。如何在每次调用 seqLength 之前强制对其进行评估?顺便说一句,memoization 实施得好吗?比起解决练习,我更感兴趣的是指出我的 Haskell 错误。
【问题讨论】:
-
顺便说一句,对于这个问题,您可能希望使用
arrayRange组合器——因为序列中的值变得非常大,备忘录查找变得更加昂贵(integral的日志时间)和不太可能被重复使用。对于足够大的值,最好忽略记忆。
标签: haskell stack-overflow memoization