Fibonacci summation in lisp

I have just started to learn Lisp, and I am working on some Project Euler issues. I am stuck on where you sum even the Fibonacci numbers below the maximum number. What I tried goes further. I read this post , but I still don't know why none of my methods work!

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 
+4
source share
3 answers

You end the do loop as soon as max greater than sum , which happens in the very first iteration.

After you switch this > to < , you get an arithmetic error, because ultimately you will bind sum to nil (when upgrading to (if (evenp curr) (+ sum curr)) , which is nil when (evenp curr) is false.You also need to specify an else-side: it must be sum .

More importantly, do binds its values ​​in parallel, rather than in sequence, which means that for the second iteration, when you upgrade sum to (if (evenp curr) (+ sum curr) sum) you use curr and sum from the first iteration. If this is not what you intend, you should use do* .

Update

As requested in the comments , here is the full working version of the code. Note that it is almost identical to the code in the question; it only reduces the order of the arguments to > , so that completion occurs when the curr ent of Fibonacci is greater than the value of imum max , and adds the else case to the if , so that when (evenp curr) false, the sum kept.

 (defun sum-even-fibs (max) (do ((curr 0 next) (next 1 (+ curr next)) (sum 0 (if (evenp curr) (+ sum curr) sum))) ((> curr max) sum))) 
+3
source

Slightly "better" version of arbautjc answer:

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

There are many nice features in the loop statement:

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

See link in Common Lisp HyperSpec

+1
source

All Articles