Rich Nevison
Rich Nevison

Reputation: 11

How to accumulate count in nested for loops?

I have the following:

(let ((count 0))
  (loop for i from 1 to 3 do
        (loop for j from 1 to 3 do
              (loop for k from 1 to 3 do
                    (setq count (+ 1 count))))
        finally (return count)))

Which is the fastest, lispish, construct to do this?

Upvotes: 1

Views: 419

Answers (2)

Svante
Svante

Reputation: 51501

You can use the count loop keyword in the innermost loop and sum the results in the outer loops:

(loop :for i :below 3
      :sum (loop :for j :below 3
                 :sum (loop :for k :below 3
                            :count t)))

Upvotes: 3

Terje D.
Terje D.

Reputation: 6315

What is the best way to do it depends on the purpose of the code, i.e. why you are nesting the three loops.

In your specific case, the fastest and shortest answer is (* 3 3 3) or 27

More generally, a possible improvement is to replace (setq count (+ 1 count)) with (incf count)

You can also write the loops as

(loop for i from 1 to 3 summing
   (loop for j from 1 to 3 summing
      (loop for k from 1 to 3 summing 1)))

Except for the non-looping answers, the speed should be about the same for all versions.

Upvotes: 7

Related Questions