是否有可能产生 40,000+ Lisp 中递归斐波那契元素?

发布于 2024-10-06 03:19:42 字数 535 浏览 0 评论 0原文

我正在尝试用 Lisp 解决 Project Euler 问题 2。这个递归解决方案在执行时会破坏堆栈,但我认为 Lisp(使用 clisp)会识别尾递归。这正在进入顶层。

(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))  
   "Sum fibonacci sequence, even terms up to 4 million"

   (if (> f2 4000000) sum)
   (e2-problem f2 (+ f1 f2) (if (evenp f2) 
                                (+ sum f2) 
                               sum))

我的实现是否没有正确安排优化?我想,如果我不能依赖惯用的递归,这会严重阻碍我的 Lisp 教育。

I'm trying to solve Project Euler question 2 with Lisp. This recursive solution blows the stack on execution, but I thought Lisp (using clisp) would recognize the tail recursion. This is being entered into the top-level.

(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))  
   "Sum fibonacci sequence, even terms up to 4 million"

   (if (> f2 4000000) sum)
   (e2-problem f2 (+ f1 f2) (if (evenp f2) 
                                (+ sum f2) 
                               sum))

Is my implementation not correctly arranged for optimization? I imagine this would hinder my Lisp education quite a bit if I could not rely on idiomatic recursion.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

挽手叙旧 2024-10-13 03:19:42

递归(甚至迭代)是不必要的!

每三个斐波那契数都是偶数:

1 1 2 3 5 8 13 21 34 55 89 144 ...

并且由于每个偶数斐波那契数 (粗体)是前面两个奇数斐波那契数的和,Fn 之前偶数个斐波那契数的和恰好是以下的一半所有斐波那契数列的总和,直至 Fn(如果 Fn当然是偶数)。

现在,前 n 个斐波那契数之和为 Fn+2 − 1。这很容易通过归纳法来检查:前 n+ 1 斐波那契数之和为 F1+  ;F2 + ...+ Fn +  ;Fn+1,等于 Fn+2 − 1 + 根据假设,Fn+1,根据定义等于 Fn+3 − 1斐波那契数列。

因此,如果您可以找到最大的 N 使得 F3N ≤ 4,000,000,那么要求的总和将是 ( F3N+2 − 1) / 2。

(我将把剩下的细节留给你,但从这里开始应该很简单。)

Recursion (or even iteration) is not necessary!

Every third Fibonacci number is even:

1 1 2 3 5 8 13 21 34 55 89 144 ...

and since each even Fibonacci number (in bold) is the sum of the two preceding odd Fibonacci numbers, the sum of the even Fibonacci numbers up to Fn is exactly half of the sum of all the Fibonacci numbers up to Fn (if Fn is even, of course).

Now, the sum of the first n Fibonacci numbers is Fn+2 − 1. This is easy to check by induction: the sum of the first n + 1 Fibonacci numbers is F1 + F2 + ... + Fn + Fn+1, which equals Fn+2 − 1 + Fn+1 by hypothesis, which equals Fn+3 − 1 by the definition of the Fibonacci numbers.

So if you can find the largest N such that F3N ≤ 4,000,000, then the sum that’s asked for will be (F3N+2 − 1) / 2.

(I'll leave the remaining details to you but it should be straightforward from here.)

或十年 2024-10-13 03:19:42

1) 代码中正确的语法错误

(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))  
   "Sum fibonacci sequence, even terms up to 4 million"
   (if (> f2 4000000) 
       sum   ;; here was a closing bracket 
       (e2-problem f2 (+ f1 f2) (if (evenp f2) 
                                    (+ sum f2) 
                                    sum))))  ;; 2 more brackets here

2) 使用SBCL< /a>。 CLISP 不足以检测尾递归。

3) 使用最高的可用优化级别:

(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))  
   "Sum fibonacci sequence, even terms up to 4 million"
   (declare (optimize (debug 0)))  ;; optimization
   ... 

1) Correct syntax error in code:

(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))  
   "Sum fibonacci sequence, even terms up to 4 million"
   (if (> f2 4000000) 
       sum   ;; here was a closing bracket 
       (e2-problem f2 (+ f1 f2) (if (evenp f2) 
                                    (+ sum f2) 
                                    sum))))  ;; 2 more brackets here

2) use SBCL. CLISP is not kind enough to detect tail recursion.

3) use highest available optimization level:

(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))  
   "Sum fibonacci sequence, even terms up to 4 million"
   (declare (optimize (debug 0)))  ;; optimization
   ... 
东风软 2024-10-13 03:19:42

我认为 Lisp(使用 clisp)会识别尾递归

对于实现尾调用消除的环境,Scheme 中是强制的< /a>,但在大多数其他 Lisp 方言中则不然,例如 Common Lisp。

I thought Lisp (using clisp) would recognize the tail recursion

For an environment to implement tail call elimination is mandatory in Scheme, but not in most other Lisp dialects, such as Common Lisp.

私野 2024-10-13 03:19:42

您的代码实现了无限循环。它不会终止。

使用循环:

(defun e2-problem-a (n)
  "Sum fibonacci sequence, even terms up to n"
  (loop for f1 = 1 then f2
        and f2 = 1 then (+ f1 f2)
        while (<= f2 n)
        when (evenp f2) sum f2))

Your code implements an endless loop. It does not terminate.

Using LOOP:

(defun e2-problem-a (n)
  "Sum fibonacci sequence, even terms up to n"
  (loop for f1 = 1 then f2
        and f2 = 1 then (+ f1 f2)
        while (<= f2 n)
        when (evenp f2) sum f2))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文