Re:Why 37signals Doesn't Hire Programmers Based on Brainteasers
by ericbb on Friday January 06, 2012 @02:39AM
(#3432439)
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). ;)
[ Parent
| on HN ]
Re:Why 37signals Doesn't Hire Programmers Based on Brainteasers
by digitailor on Friday January 06, 2012 @06:21AM
(#3432887)
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)))))))
Re:Why 37signals Doesn't Hire Programmers Based on Brainteasers
by ericbb on Friday January 06, 2012 @01:17PM
(#3434352)
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)))))
Re:Why 37signals Doesn't Hire Programmers Based on Brainteasers
by digitailor on Friday January 06, 2012 @04:00PM
(#3435000)
Thanks!
With the macro you can use arbitrary divisors though ;)
Any desire to refactor that beast?