Here's the challenge. It's a classic since it's easy but not that obvious. I'll accept any code that I can run that satisfies the requirement but bonus points for elegance and economy. Please record the time it takes you to finish and any other notes you'd like to include.
“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".”
- 1
- 2
- Fizz
- 4
- Buzz
- Fizz
- 7
- 8
- Fizz
- Buzz
- 11
- Fizz
- 13
- 14
- FizzBuzz
- 16
- 17
- Fizz
- 19
- Buzz
- Fizz
- 22
- 23
- Fizz
- Buzz
- 26
- Fizz
- 28
- 29
- FizzBuzz
- 31
- 32
- Fizz
- 34
- Buzz
- Fizz
- 37
- 38
- Fizz
- Buzz
- 41
- Fizz
- 43
- 44
- FizzBuzz
- 46
- 47
- Fizz
- 49
- Buzz
- Fizz
- 52
- 53
- Fizz
- Buzz
- 56
- Fizz
- 58
- 59
- FizzBuzz
- 61
- 62
- Fizz
- 64
- Buzz
- Fizz
- 67
- 68
- Fizz
- Buzz
- 71
- Fizz
- 73
- 74
- FizzBuzz
- 76
- 77
- Fizz
- 79
- Buzz
- Fizz
- 82
- 83
- Fizz
- Buzz
- 86
- Fizz
- 88
- 89
- FizzBuzz
- 91
- 92
- Fizz
- 94
- Buzz
- Fizz
- 97
- 98
- Fizz
- Buzz
- Capital letters
- Says "prints the numbers" but what does that mean? Is printing to console technically wrong?
- It's unclear whether the Buzz should print the number.
- It's unclear how to separate the results.
- It's not clear whether this would need to be flexible enough to be used in other places.
//JavaScript
(function(){
'use strict';
for(var i=0;i<101; i++){
if((i%3 == 0) && (i%5 == 0)) {
console.log('FizzBuzz');
}
else if(i%3 == 0) {
console.log('Fizz');
}
else if(i%5 == 0) {
console.log('Buzz');
}
else {
console.log(i);
}
}
})();
- This actually goes from 0 to 100.
- Using <= 100 rather than < 101 does a better job of comunicating to the reader what was intended with this loop.
- Basically gets the job done. BTW, this is what most solutions look like in most languages.
// JavaScript
// (Assumes there is a div in the dom with id="output")
var output = "",
outputSelector = document.querySelector("#output");
for(var i=1; i<=100; i++) {
if( i % 3 == 0 && i % 5 == 0) {
output += "FizzBuzz<br>";
continue;
}
if( i % 3 == 0 ) {
output += "Fizz<br>";
continue;
}
if( i % 5 == 0 ) {
output += "Buzz<br>";
continue;
}
output += (i + "<br>");
}
outputSelector.innerHTML = output;
- First one to output to HTML instead of console. Interesting how this increases the level of coupling to other code.
is part of the output. Is that part of requirements? This could be added once at the final line instead of sprinkled throughout the code.- Uses two checks for divisibility for each number instead of combining the strings after each check. By the way, why did nobody check for i % 15 == 0?
// C++
void main(){
bool printNum = true;
for (int i=0; i<100; i++){
printNum = true;
if (i%3==0){
cout << "Fizz";
printNum = false;
}
if (i%5==0) {
cout << "Buzz";
printNum = false;
}
if (printNum) {
cout << i;
}
cout << "\n";
}
}
- Because cout requires you to explicitly create a newline (unlike console.log), this solution is able to build a string by simply outputting it. This saves one comparison conditional statement since for multiples of both 3 and 5, the "Fizz" already has been output.
- At first glance, I was like "Why do they have a boolean just to track the result of the conversion? Why not use the string itself?" But then I realized that there is no string, the result is written directly to the standard output without an intermediary variable. By using a Boolean, this program keeps its overhead stack memory to 1 bit.
- The business logic (if statements) is tied to user interface logic (cout). This could be improved by making a separate FizzBuzz() function.
- No comments.
http://stackoverflow.com/questions/16620665/fizzbuzz-programdetails-given-in-javascript#answers
- This person simply linked to the problem being solved online. I'm pretty sure it was intended to mock this exercise but I feel like this is a very clever entry. There really is no reason to solve a problem that has already been solved.
- Technically the challenge was to "Write a program..."
- If someone showed me this in an interview, I would be very impressed. However, I would still want them to be able to at least explain the algorithm or be able to implement it without copying the work.
I wanted to compare some more extreme examples of soliving this problem with different styles of coding.
// JavaScript
function fizzbuzz(n) {
var str = "";
if (n % 3 == 0) str += "fizz";
if (n % 5 == 0) str += "buzz";
if (!str) str = n.toString();
return str;
}
var n = 0;
while (n++<100) {
console.log(fizzbuzz(n));
}
- Saves a conditional by building the string as it goes.
- Might not totally qualify since the result is printed to the console instead of the UI.
- No comments and it's a little hard to read. Using more descriptive names and curly braces and spacing everything out might make it a bit more human.
- Oh no! I forgot to capitalize "Fizz" and "Buzz". This could be an issue in the real world.
- I was somewhat surprised to see that this was the only entry to make the conversion function separate from the loop function. While this isn't an explicit requirement, this is important because it makes it more reusable, testable, and cacheable. If your hypothetical client came back and said, "Ok, now we need to FizzBuzz the numbers 350 to 975 in a different part of the app" you would already have the core business functionality written.
function multiplesOf(n) {
return function (i) {
return (i % n === 0);
}
}
function replace (matches) {
return {
with : function (string) {
return function (i) {
return (matches.indexOf(i) >= 0) ? string : i;
}
}
}
}
// create set of numbers
var i=0,a=[]; while (i++<100) a.push(i);
var threeAndFive = a.filter(multiplesOf(3)).filter(multiplesOf(5));
var three = a.filter(multiplesOf(3));
var five = a.filter(multiplesOf(5));
document.getElementById("out").innerHTML = a
.map(replace(threeAndFive).with("FizzBuzz"))
.map(replace(three).with("Fizz"))
.map(replace(five).with("Buzz"))
.join("<br />");
// JavaScript
// (Assumes there is an html element with id "o")
for(n=1;n<=100;n++)o.innerHTML+=(n%3&&n%5?n:((!(n%3)?"Fizz":"")+(!(n%5)?"Buzz":"")))+"<br>";
/**
* Takes an integer and returns "Fizz" if that integer is divisible by 3,
* "Buzz" if that integer is divisible by 5, and "FizzBuzz" if it's divisible
* by both 3 and 5. Otherwise, it returns the input number.
*
* @author Mims Wright
*
* @function convertNumberToFizzBuzzString
* @param num {Number} The input number.
* @returns {String} Either "Fizz", "Buzz", "FizzBuzz" or a number.
*/
function convertNumberToFizzBuzzString(num) {
'use strict';
/** @type {String} */
var convertedNumber = "";
// If number is divisible by 3
if (num % 3 === 0) {
convertedNumber += "Fizz";
}
// If number is divisible by 5
if (num % 5 === 0) {
convertedNumber += "Buzz";
}
// If the output hasn't been edited, then the number was neither
// divisible by 3 nor 5.
if (convertedNumber === "") {
// In that case, print the input number.
convertedNumber = num.toString();
}
return convertedNumber;
}
/**
* Test function for convertNumberToFizzBuzzString()
*/
function testConvertNumberToFizzBuzzString() {
'use strict';
// Test positive integers
console.assert(convertNumberToFizzBuzzString(1) === "1");
console.assert(convertNumberToFizzBuzzString(3) === "Fizz");
console.assert(convertNumberToFizzBuzzString(5) === "Buzz");
console.assert(convertNumberToFizzBuzzString(15) === "FizzBuzz");
// Test 0 and negatives
console.assert(convertNumberToFizzBuzzString(0) === "FizzBuzz");
console.assert(convertNumberToFizzBuzzString(-1) === "-1");
console.assert(convertNumberToFizzBuzzString(-3) === "Fizz");
console.assert(convertNumberToFizzBuzzString(-60) === "FizzBuzz");
// Test other extremes
console.assert(convertNumberToFizzBuzzString(NaN) === "NaN");
console.assert(convertNumberToFizzBuzzString(Number.MAX_VALUE) === "1.7976931348623157e+308");
console.assert(convertNumberToFizzBuzzString(Number.POSITIVE_INFINITY) === "Infinity");
}
/**
* Main function: runs the conversion function on the counting
* numbers 1 to 100 and prints the results to the screen separated by <br> tags.
*
* @param htmlElement {HTMLElement} An element to contain the results of the function.
*/
function convertFirstHundredNumbersAndOutputResultsTo (htmlElement) {
'use strict';
var counter = 1;
if (!htmlElement || htmlElement instanceof HTMLElement === false) {
throw new Error ("You must supply an HTMLElement to contain the output.");
}
while (counter <= 100) {
htmlElement.innerHTML += convertNumberToFizzBuzzString(counter) + "<br>";
counter += 1;
}
}
// Run tests.
testConvertNumberToFizzBuzzString();
// Execute main
convertFirstHundredNumbersAndOutputResultsTo ( document.getElementById('out') );