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 is
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.
-
<?php
-
$x = 100;
-
for ($i=1; $i<=$x; $i++) {
-
$msg = "";
-
if ($i % 3 == 0) {
-
$msg = "Fizz";
-
}
-
if ($i % 5 == 0) {
-
$msg = $msg . "Buzz";
-
}
-
$msg = $i;
-
}
-
print $msg . "<br/>";
-
}
-
?>
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?
I’m not sure why you define $x, then use it with $i. Couldn’t you just say $i<=100; and save a line of code?
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";
}
[…] This post was mentioned on Twitter by Amy Kate. Amy Kate said: I blogged, there's code, there's rants, there's even a pretty picture – The FizzBuzz Problem and Diving in Too Soon http://bit.ly/9b4xLC RT? […]
@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.
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/>"; }
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;
}
}
}
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 🙂
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
@Peter Someone needs to read this! http://weblog.raganwald.com/2007/01/dont-overthink-fizzbuzz.html
Here’s a one liner using a Python list comprehension. Somewhat less transparent though.
print [("FizzBuzz" if i % 3 == 0 and i % 5 == 0 else "Fizz" if i % 3 == 0 else "Buzz" if i % 5 == 0 else i) for i in range(1, 100)]
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
Abuse the print language construct for giggles 🙂
<?php
for ($x = 1; $x
@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 🙂
@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;
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";
}
I just posted my blog post about this blog post about Nick’s twitter post about a blog post.. wow that’s a bit meta.
http://bit.ly/bUShcG
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();
}
}
}
@Tony McNulty ooo, evil. I like
But… you would only have number 1 to 99 surely? the $x < 100 shoud be $x<=100 ?
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));
}
}
@Amykate And that’s why testing is so important! Good to see my solution was one of three that made the same mistake though 😉
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”.
Like to point out that mine did include 100 without having to resort to that 101 nastiness! 😛
As verbose as it is because of the program fluff
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; }
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.
My solution:
HandyFramework.FizzBuzz();
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
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.
Is that right? 🙂
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!
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 🙂
Ok my new favourite solution is Duncan’s :*)
Ternaries are only hard to understand if you are stupid 🙂
They are not hard to understand, they are harder to read. Even if you’re smart 🙂
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
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.
Very late to the party: http://fringley.wordpress.com/2010/08/27/a-little-late-on-the-fizz-buzz-problem/
[…] by The Fizz Buzz problem and diving in too soon and The Fizz Buzz Problem. Tags fizz buzz, ruby Categories […]
Well, I’m no geek, but I reckon I could still write a program for this in BASIC!
I could also easily do it in Excel…
Some things don’t require php skills! 😉