Haskell 斐波那契数之和

Haskell 斐波那契数之和,haskell,fibonacci,Haskell,Fibonacci,我对哈斯克尔是个新手。问题是找到所有偶数斐波那契数之和不超过400万。我不能使用列表 如果我理解正确,以下解决方案是错误的,因为它使用列表: my_sum = sum $ filter (odd) $ takeWhile (< 4000000) fibs 您可以在没有列表的情况下使用递归解决方案,使用 顺便说一句,运行所有斐波那契数并过滤掉奇数是解决此问题的缓慢方法。您可能会发现在excel中构建此值并从中找出代码更容易。在excel中执行此操作非常容易。把1放在第一个单元格里,然后把1

我对哈斯克尔是个新手。问题是找到所有偶数斐波那契数之和不超过400万。我不能使用列表

如果我理解正确,以下解决方案是错误的,因为它使用列表:

my_sum = sum $ filter (odd) $ takeWhile (< 4000000) fibs

您可以在没有列表的情况下使用递归解决方案,使用


顺便说一句,运行所有斐波那契数并过滤掉奇数是解决此问题的缓慢方法。

您可能会发现在excel中构建此值并从中找出代码更容易。在excel中执行此操作非常容易。把1放在第一个单元格里,然后把1放在它的正下方。然后让下面的每个单元格加上上面的两个。(即,单元格a3包含=A1+A2)。使下一列仅包含偶数值“ie,if(mod(a3,2)=0,a3,0)”。下一步,把你的流动资金放在第三列。基于此,您应该能够提出递归解决方案

另一种方法是从问题开始。你只需要一个总数,它需要一个累加器

sumFib :: Integer -> Integer
sumFib threshold = sumFib' 1 1 0 threshold

sumFib' :: Integer -> Integer -> Integer -> Integer -> Integer
sumFib' n1 n2 acc threshold
你可以在上面看到我函数的签名。我构建了一个非常好的前端,需要一个阈值(4000000)来决定何时停止构建斐波那契数。然后我将它加上前两个斐波那契数和一个累加器传递给执行递归的辅助函数“sumFib”。瞧…答案是“4613732”,没有列表

n1是n-1斐波那契数,n2是n-2斐波那契数

希望有帮助

编辑:以下是我的完整解决方案:

sumFib :: Integer -> Integer
sumFib threshold = sumFib' 1 1 0 threshold

sumFib' :: Integer -> Integer -> Integer -> Integer -> Integer
sumFib' n1 n2 acc threshold
     | n1 > threshold = acc
     | otherwise = sumFib' (n2+n1) n1 newAcc threshold
            where newAcc = if n1 `mod` 2 == 0
                               then n1 + acc
                               else acc

同样,关于计算机的用途的一个非示例:

你不用电脑也能做到

第一个观察:每三个Fibo数为偶数,第一个偶数Fibo数为F_3=2

事实上:奇数+奇数=偶数;奇数+偶数=奇数;偶数+奇数=奇数,这已经结束了循环

第二次观察:F_3+F_6+F_9+…+F{3k}=1/2(F{3k+2}-1)

归纳法:F_3=2=1/2(5-1)=1/2(F_5-1)

F_3+F_6+…+F{3k+3}=1/2(F{3k+2}-1)+F{3k+3}=1/2(F{3k+2}+2F{3k+3}-1)=1/2(F{3k+4}+F{3k+3}-1)=1/2(F{3k+5}-1)

第三个观察:总和将有133333个总和,最后一个是第3999999个Fibo数

第4次观察:F_n=1/sqrt(5)*(φ^n-(1-φ)^n)

现在,我们可以将各个部分组合在一起: F_3+F_6+…+F_399999=1/2(F_4000001-1)=1/21/sqrt(5)(φ^4000001-(1-φ^4000001)-1/2=int(1/21/sqrt(5)φ^4000001)


这里int是整数部分。最后一步有效,因为-1<1-phi<0,所以(1-phi)^4000001几乎消失。你可能想用计算器来计算数值。

这是家庭作业吗?你已经试过什么了?不是家庭作业-欧拉计划。前几天我刚刚解决了这个问题。为什么你不能使用列表?@mjboggess:我写了一个基于列表的解决方案。我在寻找如何在没有列表的情况下做到这一点的技巧。@Rafal-但是为什么呢?在Haskell中,fibs有一个合适的定义——即使有一个列表,它也是懒惰的。你最好让所有这些奇妙的机器直接完成它的工作和表达解决方案。如果fibs定义正确,内存中将永远不存在实际列表!谢谢你的链接。我会查的。很乐意帮忙!从编写java开始,这是一次有趣的休息:)
sumFib :: Integer -> Integer
sumFib threshold = sumFib' 1 1 0 threshold

sumFib' :: Integer -> Integer -> Integer -> Integer -> Integer
sumFib' n1 n2 acc threshold
     | n1 > threshold = acc
     | otherwise = sumFib' (n2+n1) n1 newAcc threshold
            where newAcc = if n1 `mod` 2 == 0
                               then n1 + acc
                               else acc