Phillip Trelford's Array

POKE 36879,255

Functional Fizz Buzz

Fizz-Buzz or Bizz Buzz is a word game, popularized by Jeff Atwood in the article:

Why Can’t Programmers… Program?

The game has been turned into a simple programming test:

Write a program that prints the numbers from 1 to 100. But for multiples of 3 print "Fizz" instead of the number and for the multiples of 5 print "Buzz". For numbers which are multiples of both 3 and 5 print "FizzBuzz".

If you’re involved in hiring programmers then the article is probably worth a read.

This kind of problem can be expressed very concisely in functional programming languages to the point where the code fits in a tweet.

Haskell

Last month Calvin Bottoms posted an article describing and implementation of Fizz-Buzz in Haskell expressed in a mere 78 characters:

[max(show x)(concat[n|(f,n)<-[(3,"Fizz"),(5,"Buzz")],mod x f==0])|x<-[1..100]]

Higher order functions and list comprehensions (a feature taken from Miranda) make this very terse, but also a little impenetrable.

F#

Rather more verbose (122 characters) but perhaps a little more readable:

for n in 1..100 do printfn "%s" <| match n%3, n%5 with 
0,0 -> "FizzBuzz" | 0,_ -> "Fizz" | _,0 -> "Buzz" | _,_ -> string n

Pattern matching makes the various states relatively obvious.

Clojure

Martin Trojer sent over this quite elegant Clojure implementation via Twitter:

(map #(cond (zero? (mod % 15)) "FizzBuzz" (zero? (mod % 3)) "Fizz" 
(zero? (mod % 5)) "Buzz" :else %) (range 1 101))

Testing for “FizzBuzz” using modulus 15 helps reduce the character count.

Erlang

I’ve been playing with Erlang recently and Fizz-Buzz is my new “Hello World” app. This was my first effort:

f(101)->ok;
f(X)->Y=case{X rem 3,X rem 5}of{0,0}->fizzbuzz;{0,_}->fizz;{_,0}->buzz;
{_,_}->X end,io:format("~w~n",[Y]),f(X+1). 

Erlang doesn’t have a for loop construct built-in so I resorted to recursion instead.

That said you can achieve the same thing using the lists module seq and foreach functions:

lists:foreach(fun(X)->io:format("~w~n",[case{X rem 3,X rem 5}of{0,0}->fizzbuzz;
{0,_}->fizz;{_,0}->buzz;{_,_}->X end])end,lists:seq(1,100)).

Next?

Is Fizz-Buzz the new “Hello World”?

I think it might be, despite Jeff’s protestations, take a peek at Fizz-Buzz on Rosetta Code.

Comments (13) -

  • Keith Harrison

    3/26/2012 1:40:33 AM |

    120 chars Smile

    for n in 1..100 do printfn "%s" <| match n%3, n%5 with 0,0 -> "FizzBuzz" | 0,_ -> "Fizz" | _,0 -> "Buzz" | _ -> string n

  • Patrick J. Phillips

    3/27/2012 10:54:42 AM |

    Python

    for i in range(1,101):
        sText = str(i)
        if math.fmod(i,15) == 0: sText = "FizzBuzz"
        elif math.fmod(i,5) == 0: sText = "Buzz"
        elif math.fmod(i,3) == 0: sText = "Fizz"
        print sText

  • Antonio

    3/27/2012 12:38:51 PM |

    Perl

    #!/usr/bin/perl
    for (1..100)
    {
      unless($_ % 15) {print "FizzBuzz\n"; next;}
      unless($_ % 3)  {print "Fizz\n"; next;}
      unless($_ % 5)  {print "Buzz\n"; next;}
      print "$_\n";
    }

  • John Hanson

    3/27/2012 12:51:04 PM |

    T-SQL
    DECLARE @a INT
    SET @a = 1
    WHILE @a < 101
        BEGIN
          PRINT
              CASE WHEN @a % 15 = 0 THEN 'FizzBuzz'
                         WHEN @a % 3 = 0 THEN 'Fizz'
                         WHEN @a % 5 = 0 THEN 'Buzz'
                         ELSE CONVERT(VARCHAR(3), @a)
                    END
            SET @a = @a + 1
        END

  • gary knott

    3/27/2012 2:20:25 PM |

    /* MLAB code to fizzbuzz 1:100  [www.civilized.com]*/

    for x =1:100 do
    {s =""; if (mod(x,3)=0) s="fizz"; if (mod(x,5)=0) s=s+"buzz";
      if (s = "") type x else type s
    }  

  • itzsimpl

    3/28/2012 12:52:07 AM |

    C++ is still good [110]

    for(int i=1;i<101;i++)
        (((i%3!=0)&&(i%5!=0))?(cout<<i)Frowncout<<((i%3==0)?"Fizz":"")<<((i%5==0)?"Buzz":"")));

  • itzsimpl

    3/28/2012 1:02:19 AM |

    C++ is still good [111]

    for(int i=1;i<101;i++)
      (((i%3!=0)&&(i%5!=0))?(cout<<i):\
       (cout<<((i%3==0)?"Fizz":"")<<((i%5==0)?"Buzz":"")));

  • Arved Sandstrom

    3/28/2012 4:30:17 PM |

    I look at it this way. I interview a guy and give him a FizzBuzz type test, and he has no problems with it. What did I really just learn now that he succeeded? Not much, except that he passed a FizzBuzz test. We just killed 10 minutes or more in the interview. I'd rather stick to the tried and true, which is to give him a take-home software development assignment, which takes barely any of my time but plenty of his, and spend every minute of the valuable interview time asking intelligent questions and hopefully getting articulate replies.

    My take on FizzBuzz type programming tests - which by the way work only if given to a candidate in the flesh once he has secured a valuable interview slot - is that you must have a pretty dismal HR pre-screening process if you have to resort to that.

    But on the subject of FizzBuzz: *if* I did give someone such a test, I'd give highest marks to someone who takes the sword to the Gordian knot, and just writes out a brute-force "look for 3, 5 and 15" solution like the Python and Perl approaches offered here. Rather than being elegant when that's a waste of time.

  • joe

    4/5/2012 12:55:13 AM |

    perl -e 'print+(Fizz)[$_%3].(Buzz)[$_%5]||$_,$/for+1..100'

  • ramy

    4/8/2012 4:04:49 AM |

    java

    I know its not that slick but I liked the walk in memory lane

    for (int i = 1; i <= 100; i++) {
          if (i % 5 == 0 && i % 3 == 0)
            System.out.println("FizzBuzz");
          else if (i % 5 == 0)
            System.out.println("Buzz");
          else if (i % 3 == 0)
            System.out.println("Fizz");
          else
            System.out.println(i);
        }

  • ramy

    4/8/2012 9:00:49 AM |

    for i in range(1,101):
        if i%5==0 and i%3==0:print "FizzBuzz"
        elif i%5==0:print "Buzz"
        elif i%3==0:print "Fizz"
        else:print i

    jython

  • ramy

    4/8/2012 9:12:49 AM |

    Delete this

  • joshua

    5/29/2012 12:45:56 PM |

    Mathematica

    (If[Mod[#, 15] == 0, "FizzBuzz", If[Mod[#, 5] == 0, "Buzz",
         If[Mod[#, 3] == 0, "Fizz", #], #], #]) & /@ Range[1, 100]

Pingbacks and trackbacks (2)+

Comments are closed