A FizzBuzz Solution Explained
Welcome to Colour Me Cocoa.
Looks like you're new here. If you like what you see, you may want to subscribe to my RSS feed, or if you prefer sign up to receive email updates.
Thanks for visiting!
Jeff Atwood of The Coding Horror wrote recently about how the majority of people applying for programming jobs cannot solve even the simplest of problems within a few minutes. Naturally, upon reading this, I opened up Xcode and got cracking.
I already knew the solution upon reading the definition of the problem, but could you do it? If you’re only experience writing code is from reading this blog, then the answer is no. So lets delve further into the world of Objective-C and learn a few more tricks.
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”.
Sounds simple enough doesn’t it?
Cycling through the numbers 1 to 100 is easy. We’ve done that before. Everyone reading this should be jumping up and down going use a for loop! So that’s the first part of the problem sorted.
Deciding what to print out should be equally obvious. That is going to require some flow control. More specifically the use of an if-else statement.
Here’s where you might come unstuck. What to use for the CONDITION portion of the if-else statement. How can we easily check if a number is a multiple of another? Simple. We divide that number by the other and check to see if the remainder is zero!
% is known as the modulus operator and it does something similar. It returns the remainder of a division operation. The following are all equal to zero
3 % 3
5 % 5
6 % 3
9 % 3
10 % 5
12 % 3
15 % 3
15 % 5
Because we are using a for loop to cycle through the numbers 1 to 100, assuming we are using i as our counter we can turn the previous into two separate statements.
i % 3
i % 5
We now know how to decide when to print “Fizz” and when to print “Buzz”, and if neither of those conditions are met, when to print the number itself.
But what about the case of printing “FizzBuzz”. We need to do this when both conditions are met, the number 15 for example is both a multiple of 3 and 5.
Enter logical operators. We’ve used some of them before, the one we are interested in right now however is the Logical AND operator.
Logical AND is represented with by two ampersand symbols (&&). It is a way of chaining two CONDITION statements together.
if (i % 3 == 0 && i % 5 == 0) {
}
The above reads like so: if i%3 is equal to 0 and i%5 is equal to zero then perform what is contained within the curly braces. This solves our problem of display “FizzBuzz” instead of numbers like 15.
Our FizzBuzz problem is nearly solved. There’s just one problem. How the hell do we get NSLog to write a number to the screen? The answer is to use a string format specifier. NSLog can display a whole range of things within it’s strings, printf can do the same by the way.
Since we’re counting from 1 to 100 using an integer, the string format specifier we want to use is %d. You use it as a placeholder in your string, and then follow your string with comma separated values for each placeholder.
int i = 1
int j = 2
NSLog(@"The number %d, is not the same as the number %d", i, j)
When you run your program, the placeholders are replaced with an actual number. This is the final piece of the puzzle required to devise a solution to the FizzBuzz problem.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int i;
for (i = 1; i < 101; i++) {
if (i % 3 == 0 && i % 5 == 0) {
NSLog(@"FizzBuzz");
}
else if (i % 3 == 0) {
NSLog(@"Fizz");
}
else if ( i % 5 == 0) {
NSLog(@"Buzz");
}
else {
NSLog(@"%d", i);
}
}
[pool release];
return 0;
}
Can you improve on my solution?
April 3rd, 2007 at 10:22 pm
Yours actually prints out extra an extra Fizz when the number is divisible by both 3 and 5 because you’re first checking for 3 & 5, then going right back and checking for 3 again on the same number, so you print out:
FizzBuzz
Fizz
for one number.
This could be fixed by having the ” if (i % 3 == 0)” become an “else if” instead.
The way I did it was a little different (and uses the ternary operator, yay!). Assume everything below is within a proper for loop:
if ( i % 3 == 0 ) {
( i % 5 == 0 ) ? NSLog(@”FizzBuzz”) : NSLog(@”Fizz”);
} else if ( i % 5 == 0 ) {
NSLog(@”Buzz”);
} else {
NSLog(@”%d”,i);
}
April 3rd, 2007 at 10:37 pm
Doh! You’re right, I’ve updated the code above to include the correction.
Nice use of the ternary operator.