How to Skin a Cat: FizzBuzz 5 WaysEddie PrislacBlockedUnblockFollowFollowingFeb 22SKINAWHUTNOW?FizzBuzz is a first-year computing problem many of us have faced.
The rules are pretty simple: Given an integer, if the integer is a multiple of three, return ‘Fizz’, if the integer is a multiple of five, return ‘Buzz’, if a multiple of both three and five, return ‘FizzBuzz’, and if it’s not a multiple of either, return an empty string.
Most folks’ go-to in this situation is to whip out a simple if/else conditional, but honestly, that’s kid-stuff.
To make this a bit more difficult, today, we’ll be trying to accomplish this seemingly easy task using as few conditional statements as possible.
To make matters even more difficult, we’re gonna do it in five very different languages (and that’s where this article gets its name… “There’s more than one way to skin a cat… get it?)Eddie, you’re a madman, that’s crazy talk!~ you.
The explosion of popularity in what used to be derided by ‘real programmers’ as a ‘scripting language’ can be ascribed to the advent of node.
js and its npm ecosystem of libraries.
While in the past, it was limited to crafting cheesy animations and simple interactivity on web pages, JS can now be utilized to write entire UI frameworks, network servers, real-time chat applications, even automation and/or robotics controllers, such as those created with the Raspberry pi.
Before you say anything, I’ll be deliberately omitting type checking and error handling, just in case any of you are in school and are thinking this article is going to be a good way to cheat.
The most basic code for accomplishing FizzBuzz in JS goes like this:Simple, right?First, a few explanations:1.
If you’re just starting out, you may be wondering what that % operator is doing… that doesn’t actually mean ‘percent’.
The % is the modulus operator, and modulus is a function we’re going to make a lot of use of in this article.
Modulus is the function used when you want to find the remainder of dividing one number by another.
In this case, we want to check if the number is cleanly divisible by 3, 5 or both, so we check if the number mod 3 or 5 is equal to zero.
No, you’re not seeing triple, those triple-equals signs are the way we check equivalence in JS.
Most languages use a double-equals to check equivalence, and a single-equals for variable assignment (ex: let x = "foo").
In JS, the double-equals is used as well, but not as commonly, as the ==operator allows for type coersion; in other words, a string value of '1'would evaluate to be equivalent to a number value of 1.
That’s useful if you’re yanking the innerHTML of a tag to compare to a number in your script, but generally ill-advised.
The === operator is a strict equivalence comparison, meaning '1' === 1 would evaluate to false.
The double-ampersand ( &&)in that third conditional branch is a logical AND , but we won’t be using it again for the remainder of this article, so this will be the last time I mention it.
This code will run reasonably well, and do what it’s supposed to do.
However, it can also be written like this:Fun fact… the guy who introduced me to Immediately Invoked Function Expressions (IIFEs) refers to the parens at the end as ‘donkey balls’.
Note how the whole thing is wrapped in parens, then is followed by two empty parens… this makes the JS interpreter view the whole thing as a function that’s immediately executed when loaded, as the name implies.
In this snippet, the code is a lot cleaner-looking.
Unfortunately, because we need to instantiate Object twice, it runs about 82% slower than the first example.
If it’s slower, why would I even bother showing it to you, you might ask?.Well, performance was not the point of this demonstration, but since you asked, consider the results from this test, in which I compare the results of using an Object map vs if/else, vs case/switch.
In a case where you need to compare static results, tables have turned, and Object mapping is now 80% faster than if/else, and narrowly beats out even switch/case.
Why the flip?.In this case, if/else is the one which needs to run comparisons every time the operation is run, whereas the object is being used as a binary search tree… it’s only taking the sum and looking up the key in its structure.
This is why it’s sometimes much, much faster to utilize this type of structure than iterating over load of conditionals.
What’s more, this can be done in nearly any language that supports lists of key-value pairs, such as Python:Ooh, that’s short and sweet!Python is kinda fun.
(Image courtesy of https://www.
com/353/)In Python, we see that we can again use a reduce function, and a lot of the parts can almost be recognized from the JS version we looked at previously, even though the syntax has changed greatly.
Here, we’re using a lambda list comprehension to reduce the keys to a single string.
Also, in Python, whitespace is important… this is why I’ve used four spaces to indent my code instead of two, like in the rest of my examples — in many other languages, whitespace is a nicety, but screw it up, and it’s no big deal.
Not so in Python, if your formatting’s off even a little, it causes big problems for your code.
Even so, it’s less code than the JS version, but I couldn’t quite get away from using that ifstatement, even if it’s in a guard clause, rather than a standard conditional.
Also notice the double-equals used to determine equivalence in our modulus checkers — the === does not exist in Python, but that’s the norm, and JS is really the exception, as we’ll see in the rest of our examples…Lastly, see at the top of that code how we had to import the reduce statement?.Kinda reminds me of C++… In fact, let’s consider C++:AAAAAAAAAAIIIIIIIIIIIIGGGGGGGGHHHHHHH!!!!!!I can’t even.
HOKEY-SMOKES, BULLWINKLE, that’s a lot of code!.Of course, I did have to add an entry point (int main() ) with operations to accept input and output the results, (cin and cout) because C++ is a compiled language.
JS and Python, are interpreted languages, and can call their functions at runtime without any prep, but as I needed to be able to run the C++ code as a shell script, it was either do it this way, or script in a way to take the number param from the command-line (sorry, I just didn’t feel like it, it’s already a buttload longer without doing that).
You’ll notice that even though the syntax looks similar to JS with the parentheses wrapping the params and braces surrounding the methods, we need to do something else in C++, and that’s define the types, not only for each variable we’re using, but also for the return values of each method.
We also don’t get quite the easiest way of defining our key/value pair list, which here is called a map.
In C++, a vector takes the place of an Array, and we need to set the maximum size of the vector when defining it.
This is because C++ forces you to pay a lot closer attention to the memory being used by your program.
This is also the reason we need to include the libraries for each of the datatypes we want to use in the program up at the top of the file, because C++ will only include the bare minimum it needs to compile.
We also declared a namespace: std.
This is because all the libraries we’ve included come from the ‘standard’ library, and if we don’t declare the namespace, we end up writing out std.
in front of every declaration of a variable that uses those types.
If we’d wanted, we probably could’ve written the same program in C++ using same algorithm as in our first JS example, and it would’ve looked very similar, but still would’ve required a bit more setup and code.
JS and Python are both dynamically typed, meaning they infer the type of the variable from the data that’s assigned to the variable.
C++ on the other hand, will throw an error if you try to assign a string to a variable which you’ve defined as an int.
One final note is that hard as I try, I couldn’t get away from having at least one if/else statement, although it doesn’t appear to have one.
Can you spot it?.It’s this:string item = val?.key : "";That’s a ternary operator, and JS, Python, Ruby, C++ and virtually every other language supports them.
What’s going on here is that we’re assigning a string the value of key if val is true, else "" .
The question mark makes it shorthand for if and the colon for else.
This is what’s coined in the biz as a bit of ‘syntactic sugar’.
Gimme some sugar, Baby.
— (I always kinda hoped I’d get to work in a Bruce Campbell quote into one of my articles.
Here it is.
)OK, that’s enough about C++ for now, I need a palate-cleanser.
Let’s move on to Clojure.
Clojure is a functional language, a dialect of Common Lisp that can be run in the JVM, and can utilize Java libraries.
We won’t be getting into any of that Java stuff for now, because we really don’t need it for this example.
Be prepared, though, even though Clojure provides us with the shortest example in this list, it’s also one of the weirdest-looking:WHOA.
Yep, excluding the functions’ name, that whole method is only two lines of code, but what the hell is going on?The first thing is that the entire thing gets wrapped in a set of parentheses, (Clojure is pronounced ‘closure’, after all…), and our function declaration starts off with a defnstatement.
Also notice that the param we’ll be inputting ( num ) is wrapped in brackets instead of parens.
The other things you should notice is our tblvar is defined with a def statement, and that there are no colons separating the keys from the values.
And how about those values?.In Clojure, rather that using a % operator, we get the modulus using the mod function, and it comes before the two params… rather that writing num % 3 == 0 , we’re writing mod num 3, which will result in 0.
Why are we doing it differently than the other examples?.Well, in the list comprehension we’re using to filter down the values, you’ll see that we’re using the comp(compare) function to compare the values to zero.
If you squint really hard, that function should remind you a little of the last line of our Python example… the syntax may be different, but the structure of the line is very similar.
My final example comes from Ruby, and it makes me smile, because Ruby allows us to do something really clever.
See if you can spot it.
See it yet?Hey, you may say, that doesn’t look so special… it’s longer than all but the C++ versions of this method, but otherwise doesn’t look all that different from the JS ver… wait what… whaaaaa?.What’s that class definition doing there?.Where’s your num param?.What’s that call to self?. More details