Fizzbuzz is a game that is used as a test for basic programming skills. The game is a played as follows: Write a program that prints to STDOUT the numbers 1 to 100, but for multiples of 3 print "Fizz", for multiples of 5 print "Buzz", and for multiples of 3 and 5 print "FizzBuzz".

This appears to be a fairly basic problem, but apparently many coding interviewees still struggle. Is this problem only applicable to weeding out weak programmers? I don't think so. By twisting the constraints of the problem, you can use it as a gauge of a programmers skill or knowledge of a language. This HackerRank challenge focuses on exactly that, instead of simply supplying a working FizzBuzz solution, now you must do it in as few characters as possible.

(for the purpose of formatting code properly, assume all character counts are calculated without whitespace, and that #!/usr/bin/perl isn't included)

Let's see how few characters we can get...

If there were no constraints on the problem, I would probably write it like this:

#!/usr/bin/perl
for my $i (1..100) { if($i % 3 == 0 && $i % 5 == 0) { # or$i % 15 == 0
print "FizzBuzz\n";
}
elsif($i % 3 == 0) { print "Fizz\n"; } elsif($i % 5 == 0) {
print "Buzz\n";
}
else {
print "$i\n"; } } # 148 characters  while this a perfectly acceptable program, we can trim some fat. The if(){ ... } else if() { ... } blocks are extremely verbose, lets replace them with something more concise #!/usr/bin/perl for my$i (1..100) {
print+($i % 3 == 0 &&$i % 5 == 0) ? "FizzBuzz\n" :
($i % 3 == 0) ? "Fizz\n" : ($i % 5 == 0)                ? "Buzz\n"     :
"$i\n"; } # 106 characters  We saved 42 characters by switching to the ternary operator, pretty good, but unfortunately we also gained a character because of the unary plus + needed after the print builtin (kudos if you can tell me why). Most of the space seems to be occupied by the conditionals $i % 3 == 0, $i % 5 == 0, etc... We can probably leverage the fact that 0 is falsy in Perl to get rid of the repeated == 0. \n is also repeated 4 times, lets factor that out. #!/usr/bin/perl for my$i (1..100) {
print !($i % 3 ||$i % 5) ? "FizzBuzz" :
!($i % 3) ? "Fizz" : !($i % 5)           ? "Buzz"     :
"$i" , "\n"; } # 94 characters  We only saved 12 characters by removing all instances of == 0 with logical negations !, which isn't all that much. We still appear to be doing duplicate work however, we compute both $i % 3 and $i % 5 twice. We can save steps by noticing that Fizz is only added when $i is evenly divisble by 3, and Buzz when $i is evenly divisible by 5, so we can add them sequentially instead of testing twice. #!/usr/bin/perl for my$i (1..100) {
print +(($i % 3 ? "" : "Fizz") . ($i % 5 ? "" : "Buzz") || $i) . "\n"; } # 68 characters  Alright! We saved 26 more characters. So what else can we trim? Well...Perl has a lot of intricacies, one of which is an anonymous variable $_ so we can save few character by not needing to define $i #!/usr/bin/perl for (1..100) { print +(($_ % 3 ? "" : "Fizz") . ($_ % 5 ? "" : "Buzz") ||$_) . "\n";
}
# 67 characters


Perl also has a postfix for loop which saves us a few:

#!/usr/bin/perl
print +(($_ % 3 ? "" : "Fizz") . ($_ % 5 ? "" : "Buzz") || $_) . "\n" for(1..100); # 63 characters  and a default record separator $/ that defaults to "\n", it also turns out that we don't need to outer parens either:

#!/usr/bin/perl
print +($_ % 3 ? "" : "Fizz") . ($_ % 5 ? "" : "Buzz") || $_,$/
for 1..100;
# 57 characters


This was as low as I personally was able to get, while searching for a smaller solution I came across a pretty interesting discussion on Perl Monks about this very topic. To save you the reading if you don't feel inclined the smallest solution seems to be 48, courtesy of Sidhekin.

Sidkekin's solution:

#!/usr/bin/perl
print+(Fizz)[$_%3].(Buzz)[$_%5]||$_,$/for 1..100
# 48 characters


There is a lot going on here, so we'll break down the magic:

(Fizz) is an Array with a single element Fizz. [$_%3] is an index into that Array, if $_ is divisible by 3, then the result will be 0 and yield Fizz The same happens for Buzz and the record separator \$/ is tacked on at the end.

#### Results

FizzBuzz is a really basic problem, but modifying the problem constraints can really show what you know or think you know about a language.