FizzBuzz–A Programming Question


Projects or exercises that lend themselves to many different “correct” solutions are just about the best sorts of learning experiences I can imagine. They really open the possibilities for discussion and from discussion – questions, answers, explanations – comes real learning. Recently Dennis Shaw, a student at Old Dominion University and a Microsoft Student Partner, told me about the FizzBizz exercise. (see Using FizzBuzz to Find Developers who Grok Coding for where it comes from) This is exactly that sort of multiple solution but not that difficult sort of exercise I love. Briefly stated the exercise is:

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”.

So there you have it. It involves using some sort of conditional of course. Nested or unnested? It can be done either way. Which way is best? Do you check for multiples of three first or five? Do you check to see if the number ISN’T one of those cases  first or if it IS one of those cases? Or rather than If statements is there a different way completely? Perhaps a select/case structure? Does creating functions/methods complicate of simplify the result? If students know multiple programming languages is there one that is better for this than another (think especially about functional languages v. procedural languages). Are there special operators (like perhaps the ternary operator in C#, C/C++ and Java) that might make the code “tighter?” Is there a trade off between complication and understanding? Oh and of course, does your solution actually work?

Justify your answers. (Don’t you just just love the teacher-ness of “justify your answer?” Smile)  I can see asking students to write up an explanation of how their solution works and why they did it that way as a means for forcing examination of the solution. And as a side benefit a lot of students can benefit from yet another writing exercise. Code that can’t be explained isn’t properly understood and that causes problems in the long run. A piece of code should not be “magic” to the person who wrote it.

There are many solutions on the Internet to the FizzBuzz question. So yes, some student might go searching for one and even try to use it. The “justify your solution” question means that they still have to understand and explain how it works and why they like it. I can’t see a student saying “I like this solution because I found it on the Internet and it works.” Well, I hope they wouldn’t try that. But if they do, grade them on how well they explain the benefits of using borrowed code and if they credited the original source properly. And of course they should also be able to explain why this solution is better than others they might have found. Surely they were not so lazy as to hand in the first solution they found?

BTW a couple of related posts of mine are Teaching, Learning and the Job Interview and Characteristics of a Good Programming Project

Comments (48)

  1. Dennis Shah says:

    Here are a few more fizzbuzz-type questions: stackoverflow.com/…/alternate-fizzbuzz-questions

  2. Keith Ratliff (Dracorat) says:

    I've taken this challenge in the past.

    Here's the link to my C++ version:

    http://codepad.org/TDNUWkqV

    I've also done a C# one but it's not on codepad. (Curse them for not supporting .Net!)

    So which approach did I take? I actually approached it from the maximum readability standpoint.

    As such, I use (cringes are expected from hardcore programmers) booleans! And though I don't check for 15 specifically, the way I created the code makes 15s work out perfectly too.

    In short, the Psuedo-language for this would be "Print fizz if multiple of 3, buzz if multiple of 5, the number if neither applies." – Noting that if 3 and 5 are both true, fizz and buzz both get printed!

    I tend to avoid ternaries. They make the character count smaller true, but the readability usually suffers. They offer absolutely no compiler benefit.

    I think that covers all the questions presented herein. And I will concede that there are many "right answers" – but which is "best" is subjective.

    Mine is best, of course. Haha.

  3. Keith Ratliff (Dracorat) says:

    One more note. You might want to check out projecteuler.net if these kids of problems tickle your fancy. =)

  4. AlfredTh says:

    Actually a site that is good for this sort of thing is http://pex4fun.com Supports C#, Visual Basic and F#.

  5. anon says:

    @Keith – if mod 15 – FizzBuzz elseif mod 5 Buzz elseif mod 3 Fizz else N – if two numbers are mutually prime the only numbers that have both of them as factors has their product as a factor.

  6. Steve King says:

    @anon – mod is definitely the way to go… as a math guy that's the first thing I thought of.

  7. jonathancd says:

    I did a mathematical/binary/modular approach. Unfortunately the switch is unavoidable. https://gist.github.com/843803

    Full explanation there.

  8. Daniel Reeves says:

    Posted too soon.  Here is the better version.  Done with java but via JSP as I primarily work in web development.  Fewest lines of code I could figure to solve the problem.  I added a new line character for readability.

    for(int i=1;i<=100;i++){

    String output = "";

    if(i % 3 == 0) output = "Fizz";

    if(i % 5 == 0) output += "Buzz";

    if(output.equals("")) out.print(i+"<br>");

    else out.print(output+"<br>");

    }

  9. good 'ol mod says:

           Dim i As Integer = 1

           Dim oWrite As System.IO.StreamWriter

           oWrite = IO.File.CreateText("C:Tempfizzbuzz.txt")

           While i <= 100

               If (i Mod 3 = 0 And i Mod 5 = 0) Then

                   oWrite.WriteLine(CStr(i) + " – FizzBuzz")

               ElseIf (i Mod 3 = 0) Then

                   oWrite.WriteLine(CStr(i) + " – Fizz")

               ElseIf (i Mod 5 = 0) Then

                   oWrite.WriteLine(CStr(i) + " – Buzz")

               Else

                   oWrite.WriteLine(CStr(i))

               End If

               i = i + 1

           End While

           oWrite.Close()

  10. Programme1 says:

    This is based on a drinking game called Bizz-Buzz where you drank if you didn't get the correct numbers as each in the group counted from 1 to 100.  I lost a lot.  But, congrats on the ones who posted the code already!

  11. Zedrab says:

    If you work where I do, you set up a web service that will return the string to print given the integer input. duh.

    I am jaded.

  12. Mike Mueller says:

    FizzBuzz must be a hot topic for some reason, I saw it a few days ago on a web-design site. Over the years I have seen many plausible responses which actually helps me learn how to do things in other languages

    The one that I had not seen (at least at the time) was doing it in SQL, so I developed this version. I did get reminded that SQL chooses the first match in a case statement and ignores the rest, so the 15 was the first check. I also do know that I could use string concatenation to build it, but it does not look as graceful.

    DECLARE @Count INT

    SET @Count = 1

    DECLARE @FzBz VARCHAR(8)

    WHILE @Count <= 100 BEGIN

    SELECT @FzBz = CASE

    WHEN (@Count % 15 = 0) THEN 'FizzBuzz'

    WHEN (@Count % 3  = 0) THEN 'Fizz'

    WHEN (@Count % 5  = 0) THEN 'Buzz'

    ELSE CAST(@Count AS VARCHAR(8))

    END

    PRINT @FzBz

    SET @Count = @Count + 1

    END

  13. Jon Peterson says:

    fizzbuzz.pastebin.com/ytRhRLAq

    I love the ternaries in scripted languages, and I don't feel readability suffers because their syntax is so unique that one should know what they're looking at if they've ever encountered them before. I still think this could probably be condensed further — just have this feeling at the back of my neck that I'm missing something — but that almost certainly would impact readability.

    I'll also note that while I used "n" between integers in my sample, that was mostly because there's no practical application where this would need to be made pretty, and newline characters are two less code characters than a "<br>". 😛

    (My apologies if this is a repost. I just tried to submit, and there was no acknowledgement once the page loaded, nor was my comment listed.)

  14. Aditya says:

    C# Code

    for (int i = 1; i <= 100; i++)

               {

                   string s = "";

                   s = (i % 3 == 0) ? ((i%5==0)?"FizzBuzz":"Fizz") : ((i%5==0)?"Buzz":i.ToString()) ;

                   Console.WriteLine(s);                

               }

               Console.ReadLine();

  15. Aditya says:

    C# Code- iam dumb, reduced one more line :)

    for (int i = 1; i <= 100; i++)

               {

                  string s = (i % 3 == 0) ? ((i%5==0)?"FizzBuzz":"Fizz") : ((i%5==0)?"Buzz":i.ToString()) ;

                   Console.WriteLine(s);                

               }

               Console.ReadLine();

  16. Aditya says:

    C# Code : Man iam the dumbest c# programmer around

    for (int i = 1; i <= 100; i++)

               {

                  Console.WriteLine((i % 3 == 0) ? ((i%5==0)?"FizzBuzz":"Fizz") : ((i%5==0)?"Buzz":i.ToString()));  

               }

               Console.ReadLine();

  17. Aditya says:

    Explanation of my code

    Since 3 comes before 5, check for 3 first. If 3 works, then check for 5 too. If its both 3 & 5 it is "FizzBuzz" else only "Fizz". If 3 does not work, check for 5, if 5 works it is "Buzz" else just return the number as a string. All the above is in one line. Both AND and OR condition are handled in this one line. Should not go wrong i guess, but i may be dumb.

  18. me says:

    @Aditya: ancient god of readability should curse you

  19. Lars Kemmann says:

    Modulo was obviously my first thought, but – what about using the Sieve of Eratosthenes approach?

    Pseudocode:

    threes := bit[100]

    fives := bit[100]

    for (i := 3; i <= 100; i += 3)

        threes[i-1] = true;

    for (i := 5; i <= 100; i += 5)

        fives[i-1] = true;

    for (i := 1; i <= 100; ++i)

        if (threes[i-1] || fives[i-1])

             if (threes[i-1])

                  print "Fizz"

             if (fives[i-1])

                  print "Buzz"

        else

             print i

    Benefit: No division is necessary!  Division is much more expensive for your CPU than addition.  So, depending on the context that this program is needed for, this algorithm may be much more appropriate.  It sacrifices space complexity for the sake of time complexity.

    If you really had to, you could optimize further by replacing the "i-1" occurrences with "i" and letting the loops start and end earlier; then you would just need an "i+1" when you print out the number.  But that would require commenting your code. :)

  20. Keith Ratliff (Dracorat) says:

    @anon

    You said:

    … if two numbers are mutually prime the only numbers that have both of them as factors has their product as a factor.

    I know this. Yet the elegance of my code is that I don't have to check for that. I save a check by simply not doing the endl till after all the checks are done.

  21. pgrmdave says:

    in VB.Net:

    Imports System.Text

    Public Class BizzBuzz

       Const OUTPUT_START As Integer = 1

       Const OUTPUT_END As Integer = 100

       Private Sub cmdOutput_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOutput.Click

           Dim nums As New Dictionary(Of Integer, String)

           Dim output As New StringBuilder

           Dim line As New StringBuilder

           nums.Add(3, "bizz")

           nums.Add(5, "buzz")

           For x = OUTPUT_START To OUTPUT_END

               line.Clear()

               For Each key As Integer In nums.Keys

                   If x Mod key = 0 Then

                       line.Append(nums(key))

                   End If

               Next

               If line.Length < 1 Then

                   line.Append(x)

               End If

               line.Append(vbNewLine)

               output.Append(line)

           Next

           rtbOutput.Text = output.ToString()

       End Sub

    End Class

    This (while quick and dirty and not configurable outside of code) lends itself to being "upgraded" in the future and configured to work with different numbers and different strings.  Ideally it would read in from a database or an xml file, or at the very least the user would have the option of entering in the numbers and the strings to be used.  It's an improvement over other solutions presented here because it requires less modification when the client changes the specifications from "multiples of 3 and 5 should be replaced with 'bizz' and 'buzz' respectively" to "multiples of 1,2,3,5,7,8, and 15 should be replaces with 'jazz', 'razz', 'bizz', 'buzz', 'fizz', 'fuzz', and 'wtf' respectively".

  22. Mircea Mirea says:

    Hi Alfred,

    I consider it is an interesting problem and "some" mathematics are necessary to investigate, maybe resolve it.

    A faster solution will not use "%" or "Mod" modulo operator.

    Should we proceed?

    Thank you,

    MirceaMirea@yahoo.com

  23. Deepak Bhagchandani says:

    for(int num=0;num<=100;num++)

    {

    if(num%3==0)

    {

    if(num%5==0)

    {System.out.println("FizzBuzz"+num);}

    else

    System.out.println("Fizz"+num);

    }

    else if(num%5==0)

    {

    System.out.println("Buzz"+num);

    }

    else

    {

    System.out.println(num);

    }

    }

  24. AlfredTh says:

    Solutions that do not use modulus would be most interesting. As would discussion about why they are faster. In fact a lot more discussion of *why* options are faster or otherwise "better" are encouraged. That is in some ways more useful than just presenting a solution.

  25. Keith Ratliff (Dracorat) says:

    No mods ?? Or Division!!

    OK.

    http://codepad.org/BGRFmzbq

    Faster? Sure. By less than a human would ever notice. ^_^

  26. labi says:

    http://codepad.org/XH0ak9Lr – a solution in C without using Mod or %

  27. Matthew Dennis says:

    FWIW

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    namespace FIzzBuzz

    {

    class Program

    {

    static void Main(string[] args)

    {

    var output =  Enumerable.Range(1,100)

    .Select(i => ( (i % 3 == 0 || i % 5 == 0) ?

     (((i%3 == 0) ? "Fizz" : String.Empty) +

      ((i%5 == 0) ? "Buzz" : String.Empty))

     : i.ToString()));

    foreach (var s in output)

    {

    Console.Write(s + " ");

    }

    Console.ReadLine();

    }

    }

    }

  28. David Grider says:

    I could write this in any of the languages I know, but since I'm a VB.Net person by nature, I'll do that.

    For i As Integer = 1 To 100

    If i Mod 3 = 0 Then

    Console.WriteLine("Fizz")

    ElseIf i Mod 5 = 0 Then

    Console.WriteLine("FizzBuzz")

    Else

    Console.WriteLine(i)

    End If

    Loop

  29. AlfredTh says:

    Not quite David. Some cases are clearly missing.

  30. Keith Ratliff (Dracorat) says:

    David (and anyone else who may need an example)

    Your output for the first 15 numbers should look like this:

    01 1

    02 2

    03 Fizz

    04 4

    05 Buzz

    06 Fizz

    07 7

    08 8

    09 Fizz

    10 Buzz

    11 11

    12 Fizz

    13 13

    14 14

    15 FizzBuzz

    After that, the "Fizz" and "Buzz" pattern repeats over and over just with different numbers in between.

  31. Michael Kingsford Gray says:

    A simple list of pre-prepared answers is by far the easiest to write, to verify, to read &c.

    If this were for a safety-critical application, this would be the only approach that I would accept.

  32. Evo says:

    Would not the fastest solution that meets the brief (and only take a single line) be:

    Print("1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 etc")

  33. AlfredTh says:

    The print statement method is fast. It is only as reliable as the typist though and highly prone to cut/paste errors. And then there is the matter of scale. How easy is it to modify the routine to handle the numbers between 1 and 1,000,000,000? Or to use some arbitrary starting and ending points? Good coders think about expandability and maintainability.

  34. Jim L. says:

    Some of the languages (including C) allow you to write the most unreadable code only understood by the compiler and the writer.  If I saw something like this on the job (yes, production code),

     string s = (i % 3 == 0) ? ((i%5==0)?"FizzBuzz":"Fizz") : ((i%5==0)?"Buzz":i.ToString()) ;

    I would reject it in the code review.  Yes, it is quick, but it is not teaching the student to do a professional job.  Will this person be able to maintain it in six months?  Will someone else understand it?  How long will it take someone else to understand it.  In business, time is money.  If a programmer needs to take extra time to understand this type of code (assuming that the whole program is written like this), then your business is wasting valuable time and money.  Something like

    String output = "";

    if(i % 3 == 0) output = "Fizz";

    if(i % 5 == 0) output += "Buzz";

    if(output.equals("")) out.print(i+"<br>");

    else out.print(output+"<br>");

    As a teacher preparing students for their professional life as software engineers, it is most important to instill the idea that code readability is important.

  35. Abi Ullattil says:

    Was playing a bit with C++ syntax and came up with this…

    #include <iostream>

    #include <iomanip>

    bool setFalse(bool& var)

    {

       var = false;

       return true;

    }

    int main()

    {

    bool printNum;

    for(int i = 1; i < 101; ++i)

    {

       printNum = true;

       std::cout<<std::setw(3)<<std::setfill('0')<<i<<std::setw(0)<<" : ";

       std::cout<<(i%3==0?(setFalse(printNum)?"Fizz":""):"")<<(i%5==0?(setFalse(printNum)?"Buzz":""):"");

       printNum?std::cout<<i:std::cout;

       std::cout<<std::endl;

    }

    return 0;

    }

  36. katarmal vicky says:

    If any one have a problem about asp.net than told me i solve it send me your problem on katarmalvk@gmail.com

  37. Neeraj Gupta says:

    A simple solution without mod.

    int main()

    {

       int counter3=0;

       int counter5=0;

       int flag=0;

       int i=0;

       for(i=1;i<=100;i++)

       {

               flag=1;

               printf("%d ",i);

               if(++counter3==3) {counter3=0; printf("Fizz"); flag=0;}

               if(++counter5==5) {counter5=0; printf("Buzz"); flag=0;}

               if(flag) printf("%d",i);

               printf("n");

       }

    }

  38. masterLoki says:

    My Python answer

    g = lambda(i):(i%3==0 and i%5==0 and 'FizzBuzz') or (i%3==0 and 'Fizz') or (i%5==0 and 'Buzz') or i

    for i in range(1,101):

     print g(i)

  39. Adam says:

    Although it's not the most efficient way (it could be done with modulo), here is my solution. I've allowed expansion to an arbitrary number of search terms, as most solutions already presented are hard-coded to 3 and 5, and would make it difficult or impractical to add, for instance, "Woo" on every instance of 2 (making 30, 60 and 90 "WooFizzBuzz").

               int number, i;

               int[] count;

               string output;

               int [] multipler = {3, 5}; // add numbers here

               string[] words = {"Fizz", "Buzz"}; // corresponding words

               count = new int[multipler.Length]; // use a count rather than modulo

               for (i = 0; i < count.Length; i++)

                   count[i] = 1;

               for(number = 1; number <= 100; number++)

               {

                   output = "";

                   for (i = 0; i < multipler.Length; i++)

                   {

                       if (count[i] == multipler[i])

                       {

                           output += words[i];

                           count[i] = 0;

                       }

                       count[i]++;

                   }

                   if (output == "")

                       output = number.ToString();

                   Console.WriteLine(output);

               }

               Console.ReadLine();

  40. Enumerable.Range( 1, 100 ).Select(

     i =>

       i % 15 == 0 ? "FizzBuzzrn" : i % 3 == 0 ? "Fizzrn" : i% 5 == 0 ? "Buzzrn" : String.Empty

    ).ToList().ForEach(

     Console.Write

    );

    Console.ReadLine();

  41. This is what happens when you don't read the instructions properly :) Now prints the number if it's not FizzBuzz/Fizz/Buzz:

    Enumerable.Range( 1, 100 ).Select(

     i =>

       i % 15 == 0 ? "FizzBuzz" : i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : i.ToString()

    ).ToList().ForEach(

     Console.WriteLine

    );

    Console.ReadLine();

  42. …and the fixed aggregate version:

    Console.Write(

     Enumerable.Range( 1, 100 ).Aggregate(

       String.Empty, ( current, i ) =>

         current + ( i % 15 == 0 ? "FizzBuzz" : i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : i.ToString() ) + "rn"

     )

    );

    Console.ReadLine();

  43. Extensible version (similar to Adam's but more LINQy):

    var words = new Dictionary<int, string> {{3, "Fizz"}, {5, "Buzz"}};

    Enumerable.Range( 1, 100 ).Select(

     i =>

       words.Any( wordPair => i % wordPair.Key == 0 ) ?

         words.Where( wordPair => i % wordPair.Key == 0 ).Aggregate(

           String.Empty, ( current, wordPair ) =>

             current + wordPair.Value

         )

       :

         i.ToString()

    ).ToList().ForEach( Console.WriteLine );

    Console.ReadLine();

  44. Bob says:

    Would the students get any credit for pointing out that there is an infinite number of "the numbers from 1 to 100"?

  45. AlfredTh says:

    A good question. The proper answer is probably to specify Integers between 1 and 100. :-)

  46. Keith Ratliff (Dracorat) says:

    I would say that it goes without saying that unless specified otherwise, if you're given requirements in integers, then the expected results is also specified in integers.

    The ability to understand natural language is import to being a good programmer. If for some reason there was confusion (such as a requirement that states "measure all objects between 1 foot and 5 feet in length and store them in this database" – which would cause confusion over what to do with partial measurements) then one would ask questions in order to understand the requirements more fully.

    I've had the unfortunate experience of working with contractors that took the approach of pointing out inane trivialities with language – such as "but there are an infinite number of numbers between X and Y" and I will not hire them back. Such people are not only unproductive, but they excel at creating rabbit holes and then falling in them.

    That's not to say if someone was legitimately confused over the requirements that I wouldn't answer clarification questions, but these people were not confused. They simply have the unfortunate habit of trying to look important or highly educated, or something. I'm never quite sure. But they come across as difficult to work with at best. Jerks at worst.

    It probably goes without saying, but if I gave this question in interview and a candidate said "there are an infinite number of numbers between 1 and 100" I wouldn't hire them. That would be an immediate disqualifier. If on the other hand, they said "integers only?" then I'd confirm integers only and wouldn't think any less of them.

  47. Mary Attenborough says:

    Ability to see what is missing in a specification can be an important quality.  Interestingly the formation of this problem has a missing requirement. The first sentence should read "Write a program that prints the numbers from 1 to 100 in order". The words 'in order' are missing.

  48. Scott P says:

    // Sans strong-typing…

    for( var i = 1: i <= 100; i++){

    var multipleOf3 = (i % 3) == 0;

    var multipleOf5 = (i % 5) == 0;

    var t = multipleOf3 ?

    ( multipleOf5 ? "fizzbuzz" : "fizz")

    : ( multipleOf5 ? "buzz" : i);

    print( t);

    }

    /* Advantages:

    *   Evaluate i % 3 and i % 5 only once for each i

    *   It's kind-of readable if you are ok with ternaries

    *   The coercion of i to a string is here left to the language, but inexpensive algorithms for this are a commodity

    * To implement with stronger typing, this coercion would need to be explicitly performed or delegated

    */