FizzBuzz
Some people who don't ask my opinions on things got together and made some decisions. As a result of this, I find myself unexpectedly looking for work as a software engineer. To make that easier, I feel compelled to show off to the world that I can code out a decent implementation of FizzBuzz.
Uh...
Well, okay. Let's talk about tradeoffs. On the one hand, this approach is very clear. You know exactly what will get printed in what order. There's merit to being concrete in this way.
But, what if I want to go past 15?
I'm not sure how likely that is. I've rarely seen any production code that uses more than the first two items in FizzBuzz, much less going past 15. But you're right that that is a limitation of this approach.
...
Also, there's way too much code here, and code is liability. Every additional line of code is an opportunity for a bug to sneak in, and it's just longer and harder to read. Not to mention all the duplication we've got here. I think we can do better.
Great! You're hi–
Okay, looks like that works, but we still need to clean this up something fierce.
Wait, what?
Look at all that duplication! Duplicative math, repeated string literals, and goodness knows how many
console.log statements. What a mess!
That's not really what this problem–
I mean, right now we're duplicating 'Fizz' and 'Buzz', and we're treating
15 as a special case, when it really should be a combination of 3 and 5. That fact isn't reflected anywhere
in this code. It would be much clearer if we broke this into, let's say, a multiple-of-3 case and a
not-multiple-of-3 case. Like so:
I guess I see it.
Right?? This makes the next steps so much clearer, doesn't it? Look at that first nested if-statement, where we check
x % 5. What we're really doing there is deciding whether to append 'Buzz'
to whatever came before, but that's obfuscated by the duplication of 'Fizz'.
I was just being polite. Isn't this overkill?
Never!
I... fail to see how this is an improvement.
This is so much better! Look how 'Fizz' only appears once. And sure, the x % 5 and
'Buzz' are still duplicated, but the similar structure of that duplication gives us a hint about
how to proceed.
There's more?
Yeah. If statements are ugly, but there's a trick we can use to get rid of at least some of them. We can take
advantage of the fact that if you go out of bounds in an array, Javascript will return undefined,
which then acts like false when you use the || operator. So an expression like
[foo][x] || bar will return foo when x is 0, and bar
otherwise.
I...
That's a hack! You're just abusing some corner case of array behavior.
No... I don't think so. If the designers of the language hadn't wanted code like this to be written, they wouldn't have included this feature.
...
Anyway, we're so close! The expression ['Buzz'][x % 5]
is copy-pasted exactly now, so we can get rid of that duplication, and then with just a little fiddling,
we can get rid of the outer if-statement exactly the same way. What a successful project! We're getting
rid of so much code!
...
There's still a bit more we can do. I think we do need that variable v. Otherwise, we'll wind up copy-pasting
['Buzz'][x % 5], which will waste space. But we don't need to waste time declaring it before its first
usage. We can also restructure the for loop to remove some unnecessary characters. Why waste time incrementing x
separately when we could just increment it in its check? And things like var, line-ending semicolons, and
whitespace are nice-to-haves, but they're getting in the way of us writing as little code as possible, so they have to go.
All done!
Oh thank goodness...
So what do you think? When should I start?
Uh... we'll be in touch.
I was inspired both in the specifics of this minification and in the joy of writing silly code in general by this talk at RubyConf 2016 by my friend Colin.