Historical fizzbuzz, Revision 1
FizzBuzz
In < 10 Easy Steps
Here are the requirements:
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”.
Simple, isn't it? You could probably do this with a pencil and paper in little more time than it takes to just write down the list of numbers.
Yet you might be surprised to know that a large number--some interviewers say the majority--of applicants for computer programming jobs can't write a program in the language of their own choice to do that job that in less than 15 minutes. Some can't do it at all. This is a test commonly given during job interviews, so it pays to know how.
Let's start by implementing this one line at a time:
1. Write a program that prints the numbers from 1 to 100.
print 1 print 2 print Fizz print 4 print Buzz print 6 ...
No, that isn't going to be practical at all, is it? But I've seen people try just that. Besides which, you could do the above with a typewriter or a number 2 pencil. We're supposed to use a computer here.
Using your computer, type the text below, and save it as fizz1.ex:
First try
for i = 1 to 100 do print(i) end for
Now, run your program. Type (on your computer terminal)
>eui fuzz1.ex (repeat these two save and run steps after every change to your code!)
Euphoria error message on console:
<0236>:: 'print' needs 2 arguments
Is something wrong with print? Seemed like the logical thing to do at the time. And what 2 arguments? Consulting the Euphoria docs for print, we find that the 2 arguments are integer fn and object x.
What is fn? It says "the handle to a file or device to output to". What handle? It doesn't say, but the examples imply that I can use STDOUT, which kind of makes sense.
Second try
for i = 1 to 100 do print(STDOUT,i) end for
Euphoria error message on console:
'STDOUT' (fizz1.ex:3) has not been declared.
Back to the docs--I notice that the example has a line: include std/io.e Nowhere does it say you must include that, but it's in the example, so I add it.
Third try
include std/io.e for i = 1 to 100 do print(STDOUT,i) end for 12345678910111213141516171819202122232425262728293031323334353637383940414243444 54647484950515253545556575859606162636465666768697071727374757677787980818283848 58687888990919293949596979899100
Hooray!
Now I've got my numbers. Kinda hard to read, tho.
In the docs, just below print, I see printf which kind of rings a bell, since I've been looking at various programming languages, many of which use printf frequently. Maybe that's what I need. After looking at several examples, I decide to try again.
Fourth try
for i = 1 to 100 do printf(STDOUT,"%d\n",i) end for 1 2 3 4 5 6 7 8 9 10
Now we're getting somewhere! It appears that we can now move on to line 2.
2. But for multiples of three print “Fizz“ instead of the number
OK, now the question becomes, "how do we determine whether i is a multiple of 3?".
Remembering our elementary-school math, we know that if the number can be divided by 3 without any remainder, then it's a multiple of 3.
Fifth try
for i = 1 to 100 do if remainder(i/3) = 0 then printf(1,"Fizz\n") else printf(STDOUT,"%d\n",i) end if end for <0236>:: 'remainder' needs 2 arguments if remainder(i/3) = 0 then printf(STDOUT,"Fizz\n")
Here we go again. Looking at the documentation for remainder, we find that it should have been written remainder(i,3). Weird, but OK, we'll try that.
Sixth try
for i = 1 to 100 do if remainder(i,3) = 0 then printf(1,"Fizz\n") else printf(STDOUT,"%d\n",i) end if end for 1 2 Fizz 4 5 Fizz 7 8 Fizz ...
It worked! 3 is a multiple of 3, as is 6, and 9, etc... Now you see why we run the program after each change. We're now ready to implement the next line:
3. and for the multiples of five print “Buzz”
Seventh try
for i = 1 to 100 do if remainder(i,3) = 0 then printf(STDOUT,"Fizz\n") elsif remainder(i,5) = 0 then printf(STDOUT,"Buzz\n") else printf(STDOUT,"%d\n",i) end if end for 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 ...
Success again! We're now about ready to write the next million-dollar computer game [not].
Anyway, the next part should be easy, right?
4. For numbers which are multiples of both three and five print “FizzBuzz”.
Eighth try
for i = 1 to 100 do if remainder(i,3) = 0 then printf(STDOUT,"Fizz\n") elsif remainder(i,5) = 0 then printf(STDOUT,"Buzz\n") elsif remainder(i,3) = 0 and remainder(i,5) = 0 then printf(STDOUT,"FizzBuzz\n") else printf(STDOUT,"%d\n",i) end if end for
It doesn't work. Nowhere in our list do we see FizzBuzz! The number 15, for one, is a multiple of both 3 and 5, so it should be a FizzBuzz, but isn't.
Why not? Well, it's a matter of priorities. You've already 'caught' the number 15 by the first if line (it's evenly divisible by 3), so you'll never get a chance to test if it is also divisble by 5. This oversight is known as a "bug".
The solution is to simply re-order your tests. See below.
You must also document your program by adding comments to explain what it is supposed to do (in case someone finds a bug you didn't fix!)
Ninth and final try
-- fizz1.ex -- A program that prints the numbers from 1 to 100. -- But for multiples of three it prints “Fizz” instead of the number -- and for the multiples of five it prints “Buzz”. -- For numbers which are multiples of both three and five it prints “FizzBuzz”. for i = 1 to 100 do if remainder(i,3) = 0 and remainder(i,5) = 0 then printf(STDOUT,"FizzBuzz\n") elsif remainder(i,3) = 0 then printf(STDOUT,"Fizz\n") elsif remainder(i,5) = 0 then printf(STDOUT,"Buzz\n") else printf(STDOUT,"%d\n",i) end if end for
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 ...
Congratulations!
You now know more (about writing FizzBuzz) than some CS graduates!
© 2015 by Irv Mullins
More FizzBuzz
Once you get a program working you should be happy. Or, you can look at it again and think about what you could have done differently.
Derek Parnell contributed this version:
include std/console.e integer a = 3 integer b = 5 integer c = 100 for i = 1 to c do if remainder(i,a * b) = 0 then display("FizzBuzz") elsif remainder(i,a) = 0 then display("Fizz") elsif remainder(i,b) = 0 then display("Buzz") else display(i) end if end for
- diff to current revision, view current revision history, backlinks
- Last modified Jun 15, 2015 by _tom