FizzBuzz Overanalyzed

Fizzbuzz is a common coding competency challenge that tests your ability to work with basic math and logic. The challenge is to write a block of code that accomplishes these goals:

  • Iterate over an incrementing integer. 0, 1, 2, 3… We’ll call this $i. We’ll call the current iteration $n.
  • Write “fizz” when the $n is a multiple of 3.
  • Write “buzz” when the $n is a multiple of 5.
  • Write “fizzbuzz” when both the previous conditions are met.
  • Write the value of $n if none of the above conditions are met.

Commonly the challenge might stipulate that your code should be written as a function. In this case a “fizzbuzz” function will accept one integer $n and return or print the result.

For the FizzBuzz challenge this is what I would consider a fairly typical response (as written in PHP) which we’ll call “Solution 1”:

function fizzBuzz ($n)
{
	if($n % 3 == 0 && $n % 5 == 0) {
		return 'fizzbuzz';
	} 
	else if($n % 5 == 0) {
		return 'buzz';
	} 
	else if($n % 3 == 0) {
		return 'fizz';
	} 
	else {
		return $n;
	}
}

for ($i = 1; $i < 50; $i ++) {
	echo fizzBuzz($i)."\n";
}

The output of this FizzBuzz will look something like this:

1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
17
fizz
...

The Gotchas

There’s two main ‘gotchas’ that solution 1 misses. This first is an outright error; the very first check in FizzBuzz should be for the number 0. While the sample codes on this page don’t make use of 0, it’s good to anticipate it depending on who you’re presenting a FizzBuzz to.

if($n == 0) {
	return 0;
} 

The reason for this is because the modulus operator used in FizzBuzz responses returns remainders. If a modulus operation returns 0, it’s a clean division, making it a multiple. Except for 0. 0 will always return a remainder of 0 but isn’t actually considered a multiple of integral numbers. It always surprises me know many FizzBuzz solutions neglect 0.

The second common ‘gotcha’ is known as the “15” condition. Often we see something like this:

if($n % 3 == 0 && $n % 5 == 0) {
	return 'fizzbuzz';
} 

There’s nothing wrong with this response, but it can alternatively be written as…

if($n % 15 == 0) {
	return 'fizzbuzz';
} 

The basic premise is that instead of using two checks (for 3 and 5) in the “fizzbuzz” condition, you can instead use one check for 15. Between any multiple of 3 and 5 the lowest common denominator is 15, and using that to avoid a check potentially saves hundreds of calculations if running the fizzbuzz check thousands of times.

Ultimately, there’s no wrong response to the 15 check, but I would ask any author why they used one method over the other. If they used the two-check method my preferred answer would lean towards readability or “self documentation”. Yes, it’s less efficient, but glancing at the code you more readily have an idea of what the author might be trying to do. If they used the one-check method I’d be fishing for either an answer in outright efficiency or general mathematics. If someone performed the 15 check and didn’t have an answer I’d be a bit more concerned that it’s not their logic and they just read about using 15 somewhere.

Given all this, a more thoughtful FizzBuzz response might look something like this, which we’ll call “Solution 2”;

function fizzBuzz ($n)
{
	if($n == 0) {
		return 0;
	}
	else if($n % 15 == 0) {
		return 'fizzbuzz';
	} 
	else if($n % 5 == 0) {
		return 'buzz';
	} 
	else if($n % 3 == 0) {
		return 'fizz';
	} 
	else {
		return $n;
	}
}

for ($i = 1; $i < 50; $i ++) {
	echo fizzBuzz($i)."\n";
}

Going Ternary

There is, also, further evolution of a good answer which compresses the code down by several lines, and also gives additional performance perks which we’ll call “Solution 3”;

function fizzBuzz ($n)
{
	if($n == 0) {
		return 0;
	}
	else if ($n % 3 == 0) {
		return $n % 5 ? 'fizzbuzz' : 'fizz';
	}
	else {
		return $n % 5 == 0 ? 'buzz' : $n;
	}
}

for ($i = 1; $i < 50; $i ++) {
	echo fizzBuzz($i)."\n";
}

In this more compact variant we not only look at the reduced line count, but also use more efficient codepaths. In this solution we use ternary expressions inside our return statements. Ternary expressions are essentially a more condensed if condition. The above code could be written as nested if statements, but many developers avoid nesting more than a few levels deep as it makes code progressively more difficult to navigate.

On the efficiency front this solution better accounts for modulus (%) not being an efficient operator to use, as far as operators go. Leaving aside the 0 condition the two solutions have what are called “best case” and “worst case” costs to run the function. Below shows these cases, along with the average number of % checks performed after 1000 iterations.

Best “%” CaseWorst “%” CaseAverage “%” CaseAverage Execution Time
Solution 1243.734973837.016
Solution 2132.734688097.077
Solution 32223843310.965
Number of “%” Calls per solution. Average Execution Time is against 10000 iterations with 1000 samples, compared using hrTime.

At first blush the best case scenario is better with solution 2, but solution 2’s best case only applied to one of every 15 iterations. You could shuffle the conditions so the second most efficient path applies to one third of the checks… but in general you’re just pushing a flat logic tree if you do that, when a couple of branches in logic paths will serve you better.

I don’t think anybody in their right mind would expect people to know the performance metrics of FizzBuzz. It’s not exactly real-world code, but if a developer is writing a solution to the FizzBuzz challenge beyond a competency level, I’d be very interested in seeing them push a little bit beyond the basics.

While we don’t want to try micro-optimizing this fairly trivial piece of code, it is always worth seeing when someone tends to write in more efficient manners, or at least, can. If nothing else, it’s always good to see someone push their code just a little bit harder beyond what’s strictly necessary.

Or maybe I’m just overanalyzing it.

Bash Updater

If you’re like me, you probably see the value in keeping your code in GIT repositories. If you’re like me and you also have websites running you probably pull your staged code right from git. It might not be an enterprise-grade solution, but it’s easy, we know where things are, and it’s a fairly natural workflow.

There is an issue though created by my desire for absolute laziness; it can be annoying to cd all the way into a folder, run the pull requests, and possibly do it again if I’ve exited from my ssh session but I had one more push to pull.

Of course, the natural solution is to alias a command that does everything. But it doesn’t feel particularly flexible, and I don’t like having an archive of commands which may or may not be functional. Another solution is to have something like GitHub run webhooks and such to trigger updates as you make them. While this sounds pretty hand and super simple, for me personally, I like to know exactly when my code will go live.

My solution is the below script in tandem with a dead-simple config file, which lets me get the granularity I like without the need for endless aliased commands.

#!/bin/bash

# Updates various git repositories registered in ~/git-update-locations.ini.
# Format is as follows:
# [MyProject]
# firstRepo=/path/to/first/repo
# secondRepo=/path/to/second/repo
# allRepos=/path/to/repos/*
#
# git-update.sh MyProject firstRepo
# git-update.sh MyProject allRepos
#
# If the value of a path ends with "*" it will look at all directories in that
# location, if they have a git repo, it will run the pull.
#
# For example:
# 
# [mywordpresssite.com]
# theme=/var/www/mywordpresssite.com/public_html/wp-content/themes/my-git-theme
# plugins=/var/www/mywordpresssite.com/public_html/wp-content/plugins/*
#
# git-update.sh mywordpresssite.com theme
# -> will update the theme from git.
#
# git-update.sh mywordpresssite.com plugins
# -> will update all plugins found connected to git.

if [ ! -f "$HOME/git-update-locations.ini" ]; then
	"$HOME/git-update-locations.ini not found"
	exit
fi

if [[ -z $1 ]] ; then
	echo "You must specify a registered site"
	exit
fi

if [[ -z $2 ]] ; then
	echo "You must specify a section to update"
	exit
fi

SECTION=${1//[_- ]/.}
TARGET=${2//[._ -]/"-"}
CONFIG="$HOME/git-update-locations.ini"
FOLDER=$(sed -nr "/^\[$SECTION\]/ { :l /^$TARGET[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" "$CONFIG")

if [ "$FOLDER" = "" ]; then
	echo "Target $SECTION $TARGET not found."
	exit
fi

if [[ "$FOLDER" =~ '*'$ ]] ; then 
	echo "Scanning for git repositories"
	for REPO in "${FOLDER::-1}"*; do
		[ -d "$REPO" ] || continue
		cd "$REPO"
		status="$(git rev-parse --is-inside-work-tree 2>/dev/null)"
		[ "$status" = "true" ] || continue
		echo "Updating $REPO"
		git status -s
		git pull --verbose
	done
else
	echo "Updating $FOLDER"
	cd "$FOLDER"
	git status -s
	git pull --verbose
fi

Of course, I’ve aliased this script to git-update.

alias git-update="/path/to/git-updater/git-update.sh"

Below is a portion of my own ini file, with the values used for updating this site and even the updater itself;

[kver.ca]
plugins=/var/www/kver.ca/public_html/wp-content/plugins/*
themes=/var/www/kver.ca/public_html/wp-content/themes/*
kv-design=/var/www/kver.ca/public_html/wp-content/themes/kv-design/

[utils]
updater=/opt/git-updater/

These days when updating my personal websites I just push to git, ssh into the server and have fairly quick access running my updates like so;

# Update my theme
git-update kver.ca theme

#Update all plugins connected to git
git-update kver.ca plugins

#Update the updater
git-update utils updater

Getting Glyphy With It

The newest addition is the Glyph library used on this site. It features hundreds of original icons in a convenient font-based format.

Work on the glyphs is ongoing, and I expect there to be some upheaval in the near future as the generator is upgraded. If you don’t mind that though or just want to peruse, check em’ out!

The Iconography section has been added

Over the years I’ve made hundreds of high-colour icons for various communities, sets, and projects each with their own needs, and goals.

Every set included work to design silhouettes, build out a colour palette based on the brand they would be applied to, and design phases to build out design documents and specifications. This would include asking questions such as “How will gradients be used”, “Where are the light sources”, “What perspectives will the icons use?” and more.

You can view my iconography by clicking here.

Getting Started

Welcome to my personal website and portfolio.

Things are a bit barren at the moment, but throughout the week I’ll begin populating this site with articles, resources, and much much more.