The FizzBuzz Problem and Diving in Too Soon

One of my developer friends – Nick Telford – tweeted this article about Programmers and the lack of those that seem able to programme.

Will The Real Programmers Please Stand Up? http://retwt.me/1NEBw // another example of how diluted our industry really isless than a minute ago via TweetMeme

This article linked to anothe one – Why can’t programmers…program? – which mentioned the FizzBuzz problem.

The idea is simple, all you have to do is write a program that prints out the numbers 1 to 100, but for multiples of 3, print Fizz instead of the number and for multiples of 5 print Buzz. If the number is a multiple of both, FizzBuzz should be printed.

So here’s my answer – in php of course.

  1. <?php
  2. $x = 100;
  3. for ($i=1; $i<=$x; $i++) {
  4.     $msg = "";
  5.     if ($i % 3 == 0) {
  6.         $msg = "Fizz";
  7.     }
  8.     if ($i % 5 == 0) {
  9.         $msg = $msg . "Buzz";
  10.     }
  11.     if (strlen($msg) == 0) {
  12.         $msg = $i;
  13.     }
  14.     print $msg . "<br/>";
  15. }
  16. ?>

This complies with all 4 of the requirements (numbers, Fizzes, Buzzes and FizzBuzzes), which is the point – many developers when set this task miss out one or more of the vital parts clearly stated in the specification.

It all goes back to what your mother told you when you had your first exam at school – remember to read the entire question first before diving in.

So did I miss something? Can you do it more efficiently?

38 thoughts on “The FizzBuzz Problem and Diving in Too Soon

  1. Elegant and concise solution, although I would probably make the following changes:
    – Use single quotes for constant strings.
    – Use the “append” operator instead of: $msg = $msg . “Buzz”
    – Use if ($msg == ”) rather than if (strlen($msg) == 0) as a function call is more costly than a comparison operator, and more concise.

    Actually, on the second point I’d probably use a ternary; it’s no faster, but imo it improves readability:


    <?php
    for ($i = 1; $i < 100; $i++) {
    $msg = '';
    if ($i % 3 == 0) $msg = 'Fizz';
    if ($i % 5 == 0) $msg .= 'Buzz';
    print ($msg ? $msg : $i) . "n";
    }

  2. @KarmaTiger the $x = 100 is because you just KNOW that the next thing to happen will be that “they” (client, architect etc.) will say, “that’s great, but what about for 1000?” – nice and easy to edit.

  3. I’ve been thinking again, I assign things to strings where I don’t need to..

    $x = 100;
    for ($i=1; $i< =$x; $i++) {    $printed_something = false;    if ($i % 3 == 0) {       print "Fizz";       $printed_something = true;    }    if ($i % 5 == 0) {       print "Buzz";       $printed_something = true;    }    if (!$printed_something) {       print $i;    }    print "<br/>"; }

  4. My solution which uses a KeyValuePair store to allow additional “words” to be added to the list.


    using System;
    using System.Collections.Generic;

    namespace FizzBuzz
    {
    class Program
    {
    static ICollection<KeyValuePair(int, string)> wordlist
    static void Main(string[] args)
    {
    wordlist = new Dictionary();
    wordlist.Add(new KeyValuePair(3, "Fizz"));
    wordlist.Add(new KeyValuePair(5, "Buzz"));
    PrintFizzBuzz(1, 100);
    Console.ReadKey();
    }

    static void PrintFizzBuzz(int start, int finish)
    {
    for (int i = start; i <= finish; i++)
    {
    Console.WriteLine(CalculateFizzBuzz(i));
    }
    }

    static object CalculateFizzBuzz(int i)
    {
    string CalculateFizzBuzz = "";
    foreach (KeyValuePair word in wordlist)
    {
    if (i % word.Key == 0)
    CalculateFizzBuzz += word.Value;
    }
    if (CalculateFizzBuzz.Length == 0)
    CalculateFizzBuzz = i.ToString();

    return CalculateFizzBuzz;
    }
    }
    }

  5. WRT to the $x =100 thing, using $i<=100 makes 100 a magic number, which as Amy says is "A Bad Thing".

    Although I make 1 and 100 magic numbers in my code, they are abstracted from the algorithm so the magic number is a little more acceptable 🙂

  6. Peter – C I assume? That relies on you putting the values into the dictionary in the right order I assume – to produce the “FizzBuzz” part?

    Cool

  7. Haven’t seen this in a while! it’s probably more efficient not to concat strings at all and just have another if test for the ‘fizzbuzz’ (not a php guy so don’t know for sure) – I would of done it like this in python:

    for i in range(1, 101):
    if i % 15 == 0:
    print ‘fizzbuzz’
    elif i % 3 == 0:
    print ‘fizz’
    elif i % 5 == 0:
    print ‘buzz’
    else:
    print i

  8. @Amy – It’s C# yeah. Good point about the order, technically foreach does not guarantee the order of line execution so you could get BuzzFizz for the divisor of 15. To handle that possibility I’d need to modify the foreach to be a normal for using wordlist.length.

    @Nick – I’m writing a blog post at the moment explaining my reasoning for doing it so “long winded” – essentially I wanted to show how you’d code this in a production app where magic numbers and hard coded logic is bad. Imagine if you had a set of 20 numbers with word replacements, my code would be significantly shorter than yours then, and easier to read 🙂

  9. @Amy – Mmm just reread my code and your blog stole a chunk of my code – it seems to have eaten text between triangle braces.
    wordlist should be: (replacing triangle braces with round)
    static ICollection(KeyValuePair(int, string)) wordlist;

  10. Oops, my comment was ripped into pieces there, try again:

    for ($x = 1; $x < 100; $x++) {
    $x % 3 == 0 && print 'Fizz';
    $x % 5 == 0 && print 'Buzz';
    $x % 3 && $x % 5 && print $x;
    print "n";
    }

  11. Here is my C# solution:

    using System;

    namespace FizzBuzzProblem
    {
    class Program
    {
    static void Main(string[] args)
    {
    for (int i = 1; i <= 100; i++)
    {
    string FizzBuzzString = string.Format("{0}{1}", (Math.IEEERemainder(i, 3) == 0 ? "Fizz" : ""), (Math.IEEERemainder(i, 5) == 0 ? "Buzz" : ""));
    Console.WriteLine(string.IsNullOrEmpty(FizzBuzzString) ? i.ToString() : FizzBuzzString);
    }
    Console.ReadLine();
    }
    }
    }

  12. @Tony McNulty ooo, evil. I like

    But… you would only have number 1 to 99 surely? the $x < 100 shoud be $x<=100 ?

  13. Here is my FizzBuzz

    From the “don’t over complicate it school”

    class Program
    {
    static void Main(string[] args)
    {
    Enumerable.Range(1, 100)
    .Select(i => i % 3 == 0 && i % 5 == 0 ? “FizzBuzz” : i % 3 == 0 ? “Fizz” : i % 5 == 0 ? “Buzz” : i.ToString()).ToList()
    .ForEach(s => Console.WriteLine(s));
    }
    }

  14. @Amykate And that’s why testing is so important! Good to see my solution was one of three that made the same mistake though 😉

  15. A short Python one-liner which doesn’t miss off 100:

    print 'n'.join([ (not i%3 and 'Fizz' or '') + (not i%5 and 'Buzz' or '') or str(i) for i in range(1, 101) ])

    It does exactly what was asked for (I hope) including the capitalisation of “Fizz” and “Buzz”.

  16. And here is my ruby oneliner to go with the python ones (again not missing out 100)

    (1..100).each { |x| print x % 5 == 0 && x % 3 == 0 ? “FizzBuzz” : x % 5 == 0 ? “Buzz” : x % 3 == 0 ? “Fizz” : x; }

  17. And one in JavaScript


    var r = []
    for (var i=1; i<=100; i++)
    r.push( (i%3 ? '' : 'Fizz') + (i%5 ? '' : 'Buzz') || i )
    document.body.innerHTML = r.join('<br/>')

    It could be more elegant, but again it does the job.

  18. This proved to be more difficult than I anticipated. Then again, I think my choice of language hindered me.

    Here’s the solution, in LOLPYTHON! (third time lucky – I hope code tags work):


    LOL BOOTSTRAPEENZ /LOL

    RANGE CAN HAS range
    FIZZ CAN HAS 'Fizz'
    BUZZ CAN HAS 'Buzz'
    SMASHINGZ CAN HAZ divmod

    NUFFINGZ CAN HAZ INVISIBLE STRING

    LOL HEAR WE GOEZ!!!1 /LOL

    GIMME EACH NUMBA IN THE RANGE WIT ONCE AND ALLFINGERZ OF THOSE TOEZ OF THOSE CHOKOLET ALONG WITH ONE OK?
        BLAHZ CAN HAZ NUFFINGZ
        IZ SMASHINGZ WIT NUMBA AND THR33 OK LET THE ONE OK KINDA LIKE EASTERBUNNY?
            BLAHZ GETZ ANOTHR FIZZ
        IZ SMASHINGZ WIT NUMBA AND FIV OK LET THE ONE OK KINDA LIKE EASTERBUNNY?
            BLAHZ GETZ ANOTHR BUZZ
        IZ BLAHZ?
            VISIBLE BLAHZ
        NOPE?
            VISIBLE NUMBA

  19. Amy, please format my comments for me before I lose my mind. I’ve already lost the vast majority of it trying to write that program.

    • You are correct! Slice the cecbmuur and immerse in the vodka for at least 2 hours before serving. I don’t recommend leaving the cecbmuurs in there for more than a couple days, they tend to turn a rather unappetizing color. This drink would also be great using Hendricks gin!

  20. Ternaries are evil !!
    And saving loc should not be a primary goal when writing good code!
    Not sure if a function call is always more costly than a string comparison. String comparions are function calls as well and it depends how efficiently the compiler/interpreter handles them. Definitely agree with using append instead of string concatenation.

    I like your original code best, because it’s as easy to read as a book 🙂

  21. I thought another ruby one was in order (and I was, and am still, waiting for a database to restore)….

    100.times { |x| output = ""; output << "Fizz" if x % 3 == 0; output << "Buzz" if x % 5 == 0; puts output if !output.empty? }

    • Glad you liked your present, Cathy loved Ken so much, i think she would of liked him in all the pics LOL Hope you both had a lolvey day send me some pics, i want to see cathy’s dress xxx

  22. I’m late to the party, (as always), but here we go in (I believe) ANSI compliant C:

    #include

    int main(int argc, char* argv[])
    {
    int i;

    for(i = atoi(argv[1]); i <= atoi(argv[2]); i++)
    {
    if(!(i%3))
    printf("Fizz");
    if(!(i%5))
    printf("Buzz");
    if((i%3)&&(i%5))
    printf("%d", i);
    printf("n");
    }
    }

    To satisfy the specific criteria (i.e. numbers 1 to 100), the resultant executable should be run under Windows as: “file_name 1 100” without quotes at the command prompt.

    I might also do this in Microchip MPASM PIC assembler at some point, dumping the results out to HyperTerminal.

Leave a Reply

Your email address will not be published. Required fields are marked *