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...
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".
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]
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. 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] 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");
}
}No point to this, I guess, other than that even something as simplistic as this is open to interpretation.
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... (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)))) (fizzbuzz-eval
100
'(((3 5) (print "FizzBuzz"))
((3) (print "Fizz"))
((5) (print "Buzz"))
(() print-number)))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)))))))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)))))With the macro you can use arbitrary divisors though ;)
Any desire to refactor that beast?