Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Surely, the lispiest way is to write an interpreter! Write a function fizzbuzz-eval so that the following is a solution (left as an exercise). ;)

    (fizzbuzz-eval
     100
     '(((3 5) (print "FizzBuzz"))
       ((3)   (print "Fizz"))
       ((5)   (print "Buzz"))
       (()    print-number)))


Here's a macro. There's some issues :) The biggest one is you have to make sure to put the multiple divisors list first.

The call is

  (fizzbuzz (100 (((3 5) "fizzbuzz")(3 "fizz")(5 "buzz"))))

  (defun make-cond (item)
  (let ((divisors (first item))
	(exclamation (second item)))
    (if (listp divisors)
	(let ((div1 (first divisors))
	      (div2 (second divisors)))
	  `((and (= 0 (mod n ,div1)) (= 0 (mod n ,div2)))
	    (format t "~a: ~a~%" n ,exclamation)))
      `((= 0 (mod n ,divisors)) ;else
	(format t "~a: ~a~%" n ,exclamation)))))

  (defmacro fizzbuzz (params-list)
  (destructuring-bind (num-to req-list) params-list
    (let ((cond-list '(((= 0 n)))))
      (loop for item in req-list do
	    (push (make-cond item) cond-list))
      `(dotimes (n ,num-to)
	 (cond ,@(reverse
		  (push '(t (format t "~a~%" n))
			cond-list)))))))


Hehe. That's quite a monster. I'll try to be a bit more helpful.

1. Use loop instead of dotimes so you can make the index range over 1-100 instead of 0-99.

2. Factor out the string calculation so you only need one print statement.

3. Maybe use zerop.

4. Don't write ")(". Use a space in between.

Example:

    (loop for n from 1 to 100
          do (format t "~a~%"
                     (cond
                      ((and (zerop (mod n 3))
                            (zerop (mod n 5)))
                       "FizzBuzz")
                      ((zerop (mod n 3)) "Fizz")
                      ((zerop (mod n 5)) "Buzz")
                      (t (format nil "~a" n)))))


Thanks!

With the macro you can use arbitrary divisors though ;)

Any desire to refactor that beast?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: