0

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.

2 Answers 2

5

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)))
Sign up to request clarification or add additional context in comments.

1 Comment

And in mod3or5 0 is returned "accidentally" (if there's no value clause(s), the test value is returned and 0 is non-nil, so true).
0

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.