The Fizzbuzz problem

You are given the following assignment:

You are to write a program that must fulfill these simple requirements:

For the numbers from 1 to 100,

  • If the number is a multiple of 3, print fizz instead of the number.
  • If the number is a multiple of 5, print buzz instead of the number.
  • If the number is a multiple of 15, print fizzbuzz instead of the number.
  • Otherwise, print the number itself.
  • Each output should be followed by a new line.

Can you code that and get it right in less than one minute? In less than two? How many retries will be necessary? Open your favorite editor for your favorite programming language. Ready? Set? Go!

Surprisingly enough, it is claimed that a lot of programmers can’t get it right in a very few minutes. In fact, that’s what Imran claims. Quoting from his blog:

Want to know something scary ? – the majority of comp sci graduates can’t. I’ve also seen self-proclaimed senior programmers take more than 10-15 minutes to write a solution.

I’m not sure what phenomenon he is actually witnessing there. One might be tempted to conclude that a vast majority of the programmers out there are just inept coders (and that most work at Microsoft). Surely, not all programmers are code ninjas, but I seriously doubt that many seniors are that inept. Maybe there’s another effect at play here. Maybe what Imran documented is the inherent difficulty of understanding a simple list of requirements as, well, yes, exactly, simple.

Because when you first read the list, you think of a solution that is structured as

  for (int x=1;x<=100;x++)
   {
    if (x % 3)
      // is not a multiple of 3!
      if (x % 5)
        // not a multiple of 5 either.
        cout << x;
      else
        // but is a multiple of 5!
        cout << "buzz";
    else 
      // x is a multiple of 3
      if (x % 5)
        cout << "fizz";
      else
        // is a multiple of 3 AND 5
        cout << "fizzbuzz";
    cout << endl;
   }
  return 0;

which principally enforces mutual exclusions of the cases. This leads to a needlessly complicated solution because the clauses are not as strongly mutually exclusive as you might think and nothing prevents you (the programmer) from writing a much simpler solution by following the requirements exactly, without adding any constraints that you think might be useful but that are not in the requirements. Stop thinking that “print fizz” could be replaced by a more generic processing, basically anything else. Yes, I suppose it could. Is it specified by the problem statement as it is? no. No, it’s not.

I would guess that we—all of us—do that more often that we aught to; that is, reading more into problems/assigments/requirements that there actually is; greatly complicating our lives and the code we write. Would that be a possible root cause of creeping featuritis?

*
* *

Can you do much better? I propose my solution (and it did not take me 10 minutes to find, write, and test it), but be sure to think it over at least a bit before peeking.

for (int i=1;i<=100;i++)
 {
  if ((i % 3)==0) cout << "fizz";
  if ((i % 5)==0) cout << "buzz";
  if ((i%3) && (i%5)) cout << i;
  cout << endl;
 }

28 Responses to The Fizzbuzz problem

  1. gnuvince says:

    In Haskell, like you requested:

    fizzbuzz :: Int -> String
    fizzbuzz n
        | n `mod` 3 == 0 && n `mod` 5 == 0 = "fizzbuzz"
        | n `mod` 3 == 0                   = "fizz"
        | n `mod` 5 == 0                   = "buzz"
        | otherwise                        = show n
    
    main :: IO ()
    main = mapM_ (putStrLn . fizzbuzz) [1..100]
    

    ghc –make fizzbuzz.hs and you’re good to go.

  2. Carl Tessier says:

    Qu’est-ce que ça donnerait de la part d’un étudiant de Valleyfield…

           IDENTIFICATION DIVISION.
           PROGRAM-ID.             FIZZBUZZ.
           AUTHOR.                 CARL TESSIER.
           INSTALLATION.   NONE.
           DATE-WRITTEN.   09/05/12.
    
           DATA DIVISION.
           WORKING-STORAGE SECTION.
           77      I               PIC 9(3)        VALUE ZERO.
           77      DUMMY           PIC 9(2).
           77      REM             PIC 9(2).
    
           PROCEDURE DIVISION.
               PERFORM TESTZORZ VARYING I FROM 1 BY 1 UNTIL I = 100.
               STOP RUN.
    
           TESTZORZ.
               DIVIDE I BY 15 GIVING DUMMY REMAINDER REM
               IF REM = 0 THEN
                   DISPLAY "FIZZBUZZ"
               ELSE
                   DIVIDE I BY 3 GIVING DUMMY REMAINDER REM
                   IF REM = 0 THEN
                       DISPLAY "FIZZ"
                   ELSE
                       DIVIDE I BY 5 GIVING DUMMY REMAINDER REM
                       IF REM = 0 THEN
                           DISPLAY "BUZZ"
                       ELSE
                           DISPLAY I
                       END-IF
                   END-IF
               END-IF.
    
  3. Dilb says:

    Using Python, a oneliner is more than enough:

    for i in range(100):print (`i+1`,'fizz','buzz','fizzbuzz')[(i%3==2)+2*(i%5==4)]
    
  4. Mathieu Pagé says:

    I must be some kind of super genius since I got it on the first try, in about 2 minutes.

    More seriously though, I know programmers that would fail to this kind of problem, especially in an interview context where they a) can’t run the code, b) are under time pressure and c) are stressed because the interviewer is peeking over their shoulder.

    Unfortunately, theses programmers are not the ones that read blogs like yours or Imram’s one.

  5. James Thompson says:

    Interesting post. This took me about five minutes while having my toast and coffee for breakfast.

    #!/usr/bin/perl -w

    use strict;

    my @numbers = ( 1 .. 100 );

    foreach my $n (@numbers) {
    my $printed = 0;
    if ( $n % 3 == 0 ) {
    print “fizz”;
    $printed = 1;
    }
    if ( $n % 5 == 0 ) {
    print “buzz”;
    $printed = 1;
    }

    if ( !$printed ) {
    print $n;
    }

    print “\n”;
    }

  6. Steven Pigeon says:

    Perl? and it’s readable!? Preposterous! ;)

    More seriously: the problem is not that hard and that’s why I wonder if it can really be true that senior programmers fail that miserably (as Imram claims). That it’s not transcendently elegant, hmmm, ok, maybe, but just failing to get the code right? Not so sure about that.

    • James Thompson says:

      Definitely preposterous! :)

      You can do some nice things in Perl, it’s a shame that you can also do some really nasty stuff too. I’m learning Ruby, but I still think of my programming idioms in Perl most of the time.

      I wonder how much of the problem is that people didn’t read the spec correctly? I definitely spent about 40% of my five minutes reading over the problem in detail before I really understood it, and I could imagine subtle variations on this idea nthat are not correct by the spec. On the other hand, people should be able to read, right? So maybe that’s not it, but if so there’s definitely something that doesn’t quite add up for me about this. Either people are dumber than I think, or Imran is over-representing how many people really have a problem with this program.

      I especially liked your discussion about how not to do too much for this type of a program. Some people believe that everything should be overly engineered, but really being able to hack out a quick throwaway program for a very specific task is useful, especially because your time is not free! Optimize everything, especially the amount of time you spend optimizing. :)

      • Steven Pigeon says:

        My first contact with Perl was with perl 3.something, and it really did not leave a positive impression on me. Not only most of the code I saw was of the “write-only” style, I found several “features” just positively stupid (like when you pass two lists to a function, the function only sees the contactenation of the two lists as its only parameter… that’s just retarded).

        Overengineering stuff is a typical trait of programmers. I remember a case where we needed a pipe element to do something specific (the details of what it did are unimportant). A pipe element being a program that you can use in a pipe chain in a shell script, like the usual things like grep | tr | mypipeelement | less. Of course, I went to use stdin, stdout, and the basic C-style FILE* functions. Total lines of codes, 50, or so, and it complied with the requirements and did a cromulent job. However, a friend of mine wanted a “more optimal” implementation of the pipe element and ended up (after quite a bit of time) with a Rube Goldberg contraption that tested for stdin, stdout, mapfiles, pipes file id, etc., and was over 1500 lines long. Of course, he managed to get it right (i.e., no visible bugs) but 1450 lines too long. In the end, in some (border) cases there was a speed gain, but on the order of 5 to 10%, but in the majority of normal use cases, there were no visible gain because all the gains were masked by the first disk IO at the begining of the pipe.

        But one must be careful: spending time optimizing may be the right thing to do. Going from an n^2 solution to a n \lg n solution may very well worth the few extra days of work. Even saving 5% for _one_ run may mean a lot in the end: 5% faster may mean 10 more processes running and 10 more clients serviced per CPU, which may translate eventually to massive savings as you will not need those 5 extra blade servers until a few months, or next year.

        You bring up an important point: the lifetime of the program. Indeed, if a given task is a one-shot need, one can get away with a simple script, or a quick and minimal program with no fancy optimizations whatsoever. I think that there’s a lot of “disposable” code that isn’t written as disposable code, and a lot of long-term use code that’s written as disposable code.

  7. mappy says:
    dim i, s
    for i = 0 to 100
    s = i
    if cint(i/3)=i/3 then s="fizz"
    if cint(i/5)=i/5 then s="buzz"
    if cint(i/15)=i/15 then s="fizzbuzz"
    wscript.echo s
    next
    
  8. Steven Pigeon says:

    Line 02 should be for i = 1 to 100 (not from zero).

    Asides from that, isn’t there a risk that the floating point division does not round up properly? for example, that you endup with, say, 14.9999999… instead of 15 ?

  9. Steven Pigeon says:

    moar retardedness: http://lolcode.com/contributions/cheezburger-fizzbuzz

    The fizzbuzz problem in lolcode. So much wasted time. No wonder we still do not have a cure for cancer.

  10. Pandian S says:

    DECLARE @A INT
    SELECT @A = 1

    WHILE(@A <=100)
    BEGIN
    PRINT CASE WHEN ((@A % 3) =0 AND (@A % 5) = 0 ) THEN 'FizzBuzz' WHEN (@A % 5) = 0 THEN 'Buzz' WHEN (@A % 3) = 0 THEN 'Fizz' ELSE CAST(@A AS VARCHAR) END
    SELECT @A = @A + 1
    END

  11. Josh says:

    Here’s my solution in Scheme. I made this as obnoxiously complicated as I could in two minutes.


    (define (fizzbuzz proc)
    (define (fizzbuzz-iter x)
    (cond ((= (remainder x 3) 0) (display "fizz") (fizzbuzz-iter (- x 1)))
    ((= (remainder x 5) 0) (display "buzz") (fizzbuzz-iter (- x 1)))
    ((= (remainder x 15) 0) (display "fizzbuzz") (fizzbuzz-iter (- x 1)))
    (else (display (proc x)) (fizzbuzz-iter (- x 1)))
    (fizzbuzz-iter 99)))))

    (fizzbuzz (lambda (x) (- 100 x)))

  12. Tim says:

    In about 2 minutes in VB6.
    I prefer explicit coding to implicit coding, so my solution is this…

        Dim intCounter As Integer
        
        For intCounter = 1 To 100
            If intCounter Mod 3 = 0 Then Debug.Print "fizz"
            If intCounter Mod 5 = 0 Then Debug.Print "buzz"
            If intCounter Mod 15 = 0 Then Debug.Print "fizzbuzz"
            If intCounter Mod 3  0 And intCounter Mod 5  0 And intCounter Mod 15  0 Then Debug.Print intCounter
        Next
    
    • Steven Pigeon says:

      Unless the If has an implicit else (which might entirely be the case for VB6, I don’t know), your program will print

      fizz
      buzz
      fizzbuzz

      for numbers congruent to 15.

  13. for(int i = 1; i &lt;= 100; i++)
            {
                if(i%3==0&amp;&amp;i%5==0)
                {
                    System.out.println(&quot;FIZZBUZZ&quot;);
                }
                else if(i%3==0)
                {
                    System.out.println(&quot;FIZZ&quot;);
                }
                else if(i%5==0)
                {
                    System.out.println(&quot;BUZZ&quot;);
                }
                else
                {
                    System.out.println(i);
                }
            }
    
  14. Saurabh Pandey says:
    int main() {
      for(int i=1; i<101; i++) {
        if(i%3 == 0 && i%5 == 0)
          cout << "fizzbuzz";
        else if (i%5 == 0)
          cout << "buzz";
        else if (i%3 == 0)
          cout << "fizz";
        else
          cout << i;
      }
      return 0;
    }
    
  15. Michael says:

    Dim x As Integer = 1
    For x = 1 To 100
    If x Mod 15 = 0 Then
    Console.WriteLine(“FizzBuzz”)
    ElseIf x Mod 5 = 0 Then
    Console.WriteLine(“Buzz”)
    ElseIf x Mod 3 = 0 Then
    Console.WriteLine(“Fizz”)
    Else : Console.WriteLine(x)
    End If
    Next x

  16. fozlaf says:

    Hmm, the task is not sufficiently specified, I’m afraid.
    Everybody knows what is meant, but in fact it is not clear from the description what to do. The way you defined the task rule 3 and rule 5 conflict with rule 15. You failed to define that the 15-rule has to be stronger than the two others when conflicting.
    In fact this irritated me for a short time.

    • Steven Pigeon says:

      well, that’s how the real world works, mostly. The rules are sufficiently clear, I think, even if we could have rewritten them in a different order, with something like “if a multiple of 15, or else only a multiple of 5, or else only a multiple of 3″, but at that point, the description is the program.

  17. Would this be efficient enough:

    static void Main(string[] args)
    {
    for (int i = 1; i < 101; i++)
    {
    Console.WriteLine(Process(i));

    }
    Console.ReadLine();
    }

    internal static object Process(int number)
    {
    object returnValue = null;

    if (number % 3 == 0)
    {
    returnValue += "Fizz";
    }

    if (number % 5 == 0)
    {
    returnValue += "Buzz";
    }

    if (returnValue == null)
    {
    returnValue = number;
    }

    return returnValue;
    }

  18. Dan says:

    This is how I did it – it pretty much wrote itself which I suppose means I understood what was being asked – picking up the mod 3 and mod 5 == mod 15 meant that I decided to check the output rather than run another mod check, but I would guess there isn’t much in the way of an efficiency issue using either solution

    <?php

    for($i = 1; $i <= 100; $i++)
    {
    $output = "";
    if($i % 3 == 0)
    {
    $output = "fizz";
    }
    if($i % 5 == 0)
    {
    $output .= "buzz";
    }
    if($output == "")
    {
    $output = $i;
    }
    $output .= "\n";
    echo $output;
    }

  19. Rex says:

    Dan, your code can be more optimized as follows:

    while ($i++<100) {
    $out = '';
    if (!($i % 3)) $out .= "Fizz";
    if (!($i % 5)) $out .= "Buzz";
    if (empty($out)) $out = $i;
    echo "$out\n";
    }

  20. chabika says:

    Here is my javascript solution, the result will appear in console:

    for(i=1;i<101;i++){console.log((i%3?"":"fizz")+(i%5?"":"buzz")+(i%3&&i%5?i:""));}

  21. Andy says:

    Shouldn’t the third if in your solution use || instead of &&?

      if ((i%3) || (i%5)) cout << i;

    • Andy says:

      Sorry, nevermind! I tricked myself…I was thinking that line should mean “if i is not divisible by 15″ when in fact it just means “if neither of the two previous cases matched.”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 66 other followers

%d bloggers like this: