为了解决一些问题,我需要计算帕斯卡三角形的变体,其定义如下:
f(1,1) = 1,
f(n,k) = f(n-1,k-1) + f(n-1,k) + 1 for 1 <= k < n,
f(n,0) = 0,
f(n,n) = 2*f(n-1,n-1) + 1.
对于给定的 n,我想有效地获得第 n 行 (f(n,1) .. f(n,n))。另一个限制:如果 f(n,k) >= 2^32,则 f(n,k) 应为 -1。
我的实现:
next :: [Int64] -> [Int64]
next list@(x:_) = x+1 : takeWhile (/= -1) (nextRec list)
nextRec (a:rest@(b:_)) = boundAdd a b : nextRec rest
nextRec [a] = [boundAdd a a]
boundAdd x y
| x < 0 || y < 0 = -1
| x + y + 1 >= limit = -1
| otherwise = (x+y+1)
-- start shoud be [1]
fLine d start = until ((== d) . head) next start
问题:对于非常大的数字,我得到堆栈溢出。有没有办法强制haskell评估整个列表?很明显,每一行不能包含比上限更多的元素,因为它们最终会变为 -1 并且不会被存储,并且每一行只依赖于前一行。由于惰性评估,只有每行的头部被计算,直到最后一行需要它的第二个元素,并且沿途的所有树干都被存储......我在 C++ 中有一个非常有效的实现,但我真的想知道是否有在haskell中完成它的方法也是。