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

What is a FizzBuz and what does it have to do with day to day Software Engineering?


What switz said.

It's useful as a very early screening because it eliminates a lot of people who are wasting your time and is so simple as to have almost to false negatives. It has no complexity, no algorithm or concepts you might be unfamiliar with- just the for loop, the conditional, and the modulo operator. No one who claims to be a professional developer should fail it.

For reference: http://www.codinghorror.com/blog/2007/02/why-cant-programmer...


FizzBuzz:

Write a program that prints the numbers 1 to 100. However, for multiples of 3 print "Fizz" and for multiples of 5 print "Buzz". For multiples of both 3 and 5, print "FizzBuzz".


I've gotten that one a few times, and I always write something that only contains the string 'Fizz' once and 'Buzz' once (i.e., doesn't say 'FizzBuzz' separately, just uses the same logic to print 'Fizz' and 'Buzz' both), because I figured that was partly the point; otherwise it would be "print 'Zarples' for both multiples". I've been told that it's the first time the interviewer saw it done that way, and now I see several replies here that also would take no modification to use 'Zarples' instead of 'FizzBuzz'.

No point to this, I guess, other than that even something as simplistic as this is open to interpretation.


Couldn't resist using my new Haskell skills.

show' :: Int -> String show' x

|((rem x 3 == 0) && (rem x 5 == 0)) = "FizzBuzz"

|rem x 3 == 0 = "Fizz"

|rem x 5 == 0 = "Buzz"

|otherwise = show x

main :: IO ()

main = putStrLn $ foldl (\acc x -> acc ++"\n" ++ show' x) "" [1..100]


A couple of suggestions: functions like rem look better infix:

     x `rem` 3
this means the same thing but is more readable (I think).

Instead of folding, just map putStrLn over the list:

    mapM_ (putStrLn . show') [1..100]
mapM_ is just a version of map for monads that ignores its result (it returns m () instead of m a). You can also use forM_ which is mapM_ with its arguments reversed.

Finally, I think this site lets you format code by putting four spaces in front of each line. I hope :)

Edit: One other thing. You don't need all those parentheses in the first line.

    rem x 3 == 0 && rem x 5 == 0 = "FizzBuzz"
    x `rem` 3 == 0 && x `rem` 5 == 0 = "FizzBuzz"
Both versions should work and I think they are easier to read. I could see (rem x 3 == 0) also being clear, but the outermost parentheses do not help at all.


Here's a shorter version:

  fizzbuzz x | x `mod` 3 == 0 && x `mod` 5 == 0 = "FizzBuzz"
             | x `mod` 3 == 0 = "Fizz"
             | x `mod` 5 == 0 = "Buzz"
             | otherwise = show x

  main = putStr $ unlines $ map fizzbuzz [1..100]


For us old-school types, here's the 60-second version in C:

    int main(int argc, char ** argv) 
    { 
    	int i;
    	for (i=0; i< 100; i++)
    	{
    		if( (i%3==0)&&(i%5==0)) printf("FizzBuzz");
    		else if(i%3==0)         printf ("Fizz");
    		else if(i%5==0)         printf ("Buzz");
    		else                    printf("%d",i);
    		printf("\n");
    	}
    }


A trivial piece of code that a candidate should be able to write as quickly as they can type on a computer or write on the board designed to test that (1) they can write basic code and (2) they've written enough code that trivial problems are trivial. Jeff Atwood coined the phrase [1] and gave the classic example:

   Write a program that prints the numbers from 1 to 100. But for multiples 
   of three print "Fizz" instead of the number and for the multiples of five
   print "Buzz". For numbers which are multiples of both three and five print
   "FizzBuzz".
[1] http://www.codinghorror.com/blog/2007/02/why-cant-programmer...


Can someone tell me a lispier way of doing this than

  (dotimes (n 100)
	   (cond ((= 0 n))
		 ((and (= 0 (mod n 3))(= 0 (mod n 5)))
		  (format t "~a: Fizz Buzz!~%" n))
		 ((= 0 (mod n 3))
		  (format t "~a: Fizz!~%" n))
		 ((= 0 (mod n 5))
		  (format t "~a: Buzz!~%" n))
		 (t (format t "~a~%" n))))


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: