The Kitchen Sink and Other Oddities

Atabey Kaygun

Yet Another Fizz-Buzz in Common Lisp

Description of the problem

Finally, I’ve finished a pure math project and two computational humanities projects, and I have some free time on my hand. So, I thought it is time that I wrote my own version of fizz-buzz in Common Lisp.

The code

One can find many different solutions for the problem at Rosetta Code. The solution I have is slightly different. I always hated the straightforward solution that checks divisibility by 15 first then by 5 then by 3 because the last two precludes the first. Anyway, here is yet another solution for fizz-buzz:

First, I need a function that does function composition:

(defun compose (&rest fs)
  (lambda (x)
    (let ((res x))
      (dolist (f (reverse fs) res)
        (setf res (funcall f res))))))

COMPOSE

Next, I need functions that do the right thing for a given number:

(defun do-the-right-thing (k response)
  (lambda (x) 
    (if (atom x)
        (if (zerop (mod x k)) (cons x response) x)
        (if (zerop (mod (car x) k)) (cons (car x) (cons response (cdr x))) x))))

DO-THE-RIGHT-THING

And the final code:

(let ((fizz (do-the-right-thing 3 :fizz))
      (buzz (do-the-right-thing 5 :buzz))
      (extract (lambda (x) (if (atom x) x (cdr x)))))
   (mapcar (compose extract fizz buzz) (loop for i from 0 to 50 collect i)))

((FIZZ . BUZZ) 1 2 FIZZ 4 BUZZ FIZZ 7 8 FIZZ BUZZ 11 FIZZ 13 14 (FIZZ . BUZZ)
 16 17 FIZZ 19 BUZZ FIZZ 22 23 FIZZ BUZZ 26 FIZZ 28 29 (FIZZ . BUZZ) 31 32 FIZZ
 34 BUZZ FIZZ 37 38 FIZZ BUZZ 41 FIZZ 43 44 (FIZZ . BUZZ) 46 47 FIZZ 49 BUZZ)