Reputation: 12983
I'm trying the project euler problems to learn common lisp and I'm stuck pretty early. On problem 1, the question is the sum of integers from 1 to 1000. I think the code below should do it, but it always returns the value of end
(if it's mod 3 or mod 5) or 0 instead.
(defun mod3or5 (n)
(cond
((equal (mod n 5) 0) n)
((equal (mod n 3) 0) n)
(0))))
(defun mod-sum (start end)
(cond
((equal start end) (mod3or5 start))
(+ (mod3or5 start) (mod-sum (+ start 1) end))))
For example
(mod-sum 1 9)
=> 9
(mod-sum 1 8)
=> 0
I would expect the answers to be 23 and 14 respectively.
Upvotes: 0
Views: 204
Reputation:
I've posted this before, but it was in Scheme, so I decided to rewrite it in a bit, using loop
for a change:
(defun euler-1 ()
(loop with x = (list 3 2 1 3 1 2 3)
for i in (nconc x x)
while (< (+ steps i) 1000)
summing i into steps
summing steps into result
finally (return result)))
This is how you could do it, avoiding modulo'ing (because it is expensive). You would also step 2 numbers on average (skipping those you don't have to add).
Upvotes: 0
Reputation: 370132
Each form given to cond
has the form (condition exp1 ... expn)
. If condition
is true, it will evaluate all the expressions and return the value of expn
. If condition
is false, it will continue with the next form.
Your last form is this: (+ (mod3or5 start) (mod-sum (+ start 1) end))
. So here +
is the condition (which will always be true because +
is a function and thus not nil
), (mod3or5 start)
is the first expression (which will be evaluated, but not returned) and (mod-sum (+ start 1) end)
is the last expression (which will be evaluated and then returned).
"Else branches" in cond
are implemented by choosing t
as the condition. So your last form should look like this:
(t (+ (mod3or5 start) (mod-sum (+ start 1) end)))
Upvotes: 5