在lisp中总结甚至斐波那契数字

时间:2013-05-02 01:45:40

标签: loops lisp common-lisp

我刚开始学习Lisp,我正在解决一些Project Euler问题。我被困在那个你将偶数斐波那契数字加到最大数字之下的那个。我尝试过的事情如下。我读过this post,但我仍然不确定为什么我的方法都不起作用!

CL-USER> (defun sum-even-fibs (max)
           (do ((curr 0 next)
                (next 1 (+ curr next))
                (sum  0 (if (evenp curr) (+ sum curr))))
               ((> max curr) sum)))
SUM-EVEN-FIBS
CL-USER> (sum-even-fibs 10)
0


CL-USER> (defun sum-even-fibs (max)
           (let ((sum 0))
             (do ((curr 0 next)
                  (next 1 (+ curr next)))
                 ((> max curr))
               (if (evenp curr) 
                   (setq sum (+ sum curr))))
             (format t "~d" sum)))
SUM-EVEN-FIBS
CL-USER> (sum-even-fibs 10)
0
NIL

3 个答案:

答案 0 :(得分:5)

arbautjc答案稍微“更好”的版本:

(loop for a = 0 then b and b = 1 then (+ a b) 
      while (< a 4000000) 
      when (evenp a) sum a)

答案 1 :(得分:3)

只要do大于max,就会在第一次迭代时发生sum循环。

>切换为<之后,您将收到算术错误,因为您最终会将sum绑定到nil(更新时)当(if (evenp curr) (+ sum curr))为false时nil(evenp curr)。您还需要提供其他方面;它应该是sum

更重要的是,do并行绑定其值,而不是按顺序绑定,这意味着当您将sum更新为(if (evenp curr) (+ sum curr) sum)时进行第二次迭代时,您正在使用{{}第一次迭代中的1}}和curr。如果那不是你想要的,你应该考虑使用sum

更新

根据request in the comments,这是代码的完整工作版本。请注意,它几乎与问题中的代码相同;它只会将参数的顺序交换为do*,以便终止时>的Fibonacci数大于curr imum值,并将else案例添加到{{1} }表达式,以便当max为false时,保留值if

(evenp curr)

答案 2 :(得分:1)

循环指令有许多不错的功能:

(loop with a = 0 and b = 1 
      while (< a 4000000) 
      when (evenp a)
      sum a
      do (psetf a b b (+ a b)))

请参阅Common Lisp HyperSpec中的reference