<nallen05@gmail.com> wrote:
+---------------
| Rob Warnock wrote:
| > This one is both efficient -- *no* MOD calls at all! --
| > *and* so ugly only a parent could love it: ;-} ;-}
| >
| > (defun fizz-buzz (n)
| > (loop for i from 1 to n
| > and three-p in '#3=(nil nil t . #3#)
| > and five-p in '#5=(nil nil nil nil t . #5#)
| > do ...
|
| This is awsome, Rob ;-) But I can make one that's faster AND uglier!
|
| (defmacro def-fizz-buzz ()
| (let (l)
| (do* ((i 1 (incf i))
| (m3p (zerop (mod i 3))
| (zerop (mod i 3)))
| (m5p (zerop (mod i 5))
| (zerop (mod i 5))))
| ((> i 15))
| (setq l
| (list* `(print ,(cond ((and m3p m5p) "FizzBuzz")
| (m3p "Buzz")
| (m5p "Fizz")
| (t 'y)))
| '(when (> y x) (return))
| '(incf y)
| l)))
| `(defun fizz-buzz (x)
| (let ((y 0))
| (loop ,@(reverse l))))))
+---------------
Yes!! *That's* how to use macros to write code for you!! ;-}
One minor tweak -- instead of:
(INCF Y)
(WHEN (> Y X) (RETURN))
you could use:
(WHEN (> (INCF Y) X) (RETURN))
Another really minor tweak -- in the DO* variable bindings,
instead of (M3P (ZEROP (MOD I 3)) (ZEROP (MOD I 3)) you can
write (M3P #1=(ZEROP (MOD I 3)) #1#).
Now for *lots* of extra credit... ;-} ;-}
Write the general version of DEF-FIZZ-BUZZ that accepts a
function name (so we can tell them apart) and an alist of primes
and strings, and emits similarly-correct/fast code. E.g., the
example we've been using all along would be generated like so:
(def-fizz-buzz 'fizz-buzz '((3 "Fizz") (5 "Buzz")))
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607