Posted By

rtperson on 06/01/11

Statistics

Viewed 283 times
Favorited by 0 user(s)

Related snippets  The dread FizzBuzz question -- really, a test if your average programmer knows his or her FOR loops. The spec is that you're counting from 1 to 100. Your program should print out "fizz" if the index is divisible by three, and "buzz" if it's divisible by five, and "fizzbuzz" if it's divisible by both.

I have a couple different versions in this code: first, a few functions just fizzing or buzzing. Second, a generalization which allows any standard message against any divisor. Third, a purely functional version that zips two lists together (giving us free concatenation for "fizzbuzz"). Fourth, a list comprehension and lastly, a monadic version that calls a pure function that uses guards.

Copy this code and paste it in your HTML
1. -- file: Fizz.hs
2. -- a Haskell implementation of the fizzbuzz problem
3.
4. ns = [0..100] :: [Int]
5.
6. fizz :: Int -> String
7. fizz n = if (n `mod` 3) == 0 then "fizz" else ""
8.
9. buzz :: Int -> String
10. buzz n = if (n `mod` 5) == 0 then "buzz" else ""
11.
12. -- a generalized version. It takes the index and the value to divide against, and
13. -- returns the message if n is evenly divisible by x
14. fluff :: Int -> Int -> String -> String
15. fluff n x message = if (n `mod` x) == 0 then message else ""
16.
17. -- a purely functional implementation.
18. fizzBuzz :: [String]
19. fizzBuzz = zipWith (++) (map fizz ns) (map buzz ns)
20.
21. -- another purely functional version. Very easy to remember.
22.
23. threes :: [String]
24. threes = cycle ["", "", "Fizz"]
25.
26. fives :: [String]
27. fives = cycle ["", "", "", "", "Buzz"]
28.
29. fizzBuzzCycle :: [String]
30. fizzBuzzCycle = zipWith (++) threes fives
31.
32. -- List comprehensions, anyone?
33. boomBang :: [String]
34. boomBang =
35. [ if x `mod` 15 == 0
36. then "boombang"
37. else if x `mod` 3 == 0
38. then "boom"
39. else if x `mod` 5 == 0
40. then "bang"
41. else show x
42. | x <- ns]
43.
46. -- programming ability that he/she busts out
47. -- fizzbuzz on your butt)
48. main :: IO ()
49. main = printAll \$ map fizz' [1..100]
50. where
51. printAll [] = return ()
52. printAll (x:xs) = putStrLn x >> printAll xs
53.
54. fizz' :: Int -> String
55. fizz' n
56. | n `mod` 15 == 0 = "fizzbuzz"
57. | n `mod` 3 == 0 = "fizz"
58. | n `mod` 5 == 0 = "buzz"
59.
60. -- or, to get rid of the explicit recursion in the main routine
61. main2 :: IO ()
62. main2 = printAll \$ map fizz' ns
63. where
64. printAll xs = foldr ((>>) . putStrLn) (return ()) xs Subscribe to comments