Jaa


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

  • Anonymous
    February 23, 2011
    Here are a few more fizzbuzz-type questions: stackoverflow.com/.../alternate-fizzbuzz-questions

  • Anonymous
    February 24, 2011
    The comment has been removed

  • Anonymous
    February 24, 2011
    One more note. You might want to check out projecteuler.net if these kids of problems tickle your fancy. =)

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

  • Anonymous
    February 24, 2011
    @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.

  • Anonymous
    February 24, 2011
    @anon - mod is definitely the way to go... as a math guy that's the first thing I thought of.

  • Anonymous
    February 24, 2011
    I did a mathematical/binary/modular approach. Unfortunately the switch is unavoidable. https://gist.github.com/843803 Full explanation there.

  • Anonymous
    February 24, 2011
    The comment has been removed

  • Anonymous
    February 24, 2011
           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()

  • Anonymous
    February 24, 2011
    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!

  • Anonymous
    February 24, 2011
    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.

  • Anonymous
    February 24, 2011
    The comment has been removed

  • Anonymous
    February 25, 2011
    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>". :P (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.)

  • Anonymous
    February 25, 2011
    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();

  • Anonymous
    February 25, 2011
    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();

  • Anonymous
    February 25, 2011
    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();

  • Anonymous
    February 25, 2011
    The comment has been removed

  • Anonymous
    February 25, 2011
    The comment has been removed

  • Anonymous
    February 25, 2011
    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. :)

  • Anonymous
    February 25, 2011
    @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.

  • Anonymous
    February 25, 2011
    The comment has been removed

  • Anonymous
    February 25, 2011
    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

  • Anonymous
    February 25, 2011
    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); } }

  • Anonymous
    February 25, 2011
    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.

  • Anonymous
    February 25, 2011
    No mods ?? Or Division!! OK. http://codepad.org/BGRFmzbq Faster? Sure. By less than a human would ever notice. ^_^

  • Anonymous
    February 25, 2011
    http://codepad.org/XH0ak9Lr - a solution in C without using Mod or %

  • Anonymous
    February 25, 2011
    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(); } } }

  • Anonymous
    February 25, 2011
    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

  • Anonymous
    February 25, 2011
    Not quite David. Some cases are clearly missing.

  • Anonymous
    February 25, 2011
    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.

  • Anonymous
    February 25, 2011
    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.

  • Anonymous
    February 25, 2011
    The comment has been removed

  • Anonymous
    February 25, 2011
    The comment has been removed

  • Anonymous
    February 25, 2011
    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.

  • Anonymous
    February 25, 2011
    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; }

  • Anonymous
    February 25, 2011
    If any one have a problem about asp.net than told me i solve it send me your problem on katarmalvk@gmail.com

  • Anonymous
    February 26, 2011
    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");    } }

  • Anonymous
    February 26, 2011
    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)

  • Anonymous
    February 26, 2011
    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();

  • Anonymous
    February 27, 2011
    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();

  • Anonymous
    February 27, 2011
    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();

  • Anonymous
    February 27, 2011
    ...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();

  • Anonymous
    February 27, 2011
    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();

  • Anonymous
    February 27, 2011
    Would the students get any credit for pointing out that there is an infinite number of "the numbers from 1 to 100"?

  • Anonymous
    February 27, 2011
    A good question. The proper answer is probably to specify Integers between 1 and 100. :-)

  • Anonymous
    February 28, 2011
    The comment has been removed

  • Anonymous
    February 28, 2011
    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.

  • Anonymous
    March 05, 2011
    // 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 */