FizzBuzz–A Programming Question

Computer Science Teacher
Computer Science Teacher - Thoughts and Information from Alfred Thompson

FizzBuzz–A Programming Question

  • Comments 48

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



  • 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();

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

  • @Aditya: ancient god of readability should curse you

  • 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. :)

  • @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.

  • 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".

  • 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

  • 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);

    }

    }

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

  • No mods ?? Or Division!!

    OK.

    http://codepad.org/BGRFmzbq

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

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

  • 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();

    }

    }

    }

  • 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

  • Not quite David. Some cases are clearly missing.

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

Page 2 of 4 (48 items) 1234