0

I have some trouble fully understanding CL's Loop macro. This is my code for Project Euler Nr. 32:

(defun number-to-list (nr)
  (map 'list #'digit-char-p (prin1-to-string nr)))

(defun nine-digits-p (multiplicand multiplier )
  (= (length (equationlist multiplicand multiplier 
                                     (* multiplicand multiplier))) 9))

(defun equationlist (multiplicand multiplier product)
  (append (number-to-list multiplicand) (number-to-list multiplier)
      (number-to-list product)))

(defun pandigital (multiplicand multiplier)
  (equal (sort (equationlist multiplicand multiplier
                 (* multiplicand multiplier)) #'<)
     '(1 2 3 4 5 6 7 8 9)))

(defun pandigital-list ()
  (loop
       for i from 1 to 2000 collect
       (loop for j from 2 to 2000
       when (and (nine-digits-p i j) (pandigital i j)) collect (* i j))))


(defun euler-32 ()
  (reduce #'+ (reduce #'union (pandigital-list))))

Although this gives me the correct solution, my problem is with function "pandigital-list". Instead of collecting only the pandigital numbers, it returns a list filled with "NIL" and the few correct numbers.

How do I change this function to only return the numbers I am interested in ?

1 Answer 1

3

The problem is that the inner loop returns nil whenever it does not collect anything else. (Remember: in Common Lisp everything has a value.)

One solution is to redefine pandigital-list like this:

(defun pandigital-list ()
   (loop for i from 1 to 2000
         for sublist = (loop for j from 2 to 2000
                             when (and (nine-digits-p i j)
                                       (pandigital i j))
                             collect (* i j))
             when sublist collect sublist))
Sign up to request clarification or add additional context in comments.

2 Comments

This can be written slightly shorter: (loop for i from i to 2000 when (loop ...) collect it). it is a predefined variable which keeps the test result.
@Rainer Joswig. Thanks. I forgot the anaphoric possibilities of loop.

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.