Code Golf

Oct 26, 2007

I stumbled across a code golf earlier this week that offers numerous problems. The specific challenge I came across was the fizz buzz problem that I had been introduced to a few weeks ago.

My initial attempt in Perl was this:

for (1..100) {
    $a = "";
    $a = "Fizz" if !($_ % 3);

1
2
3
4
5
6
7
if (!($_ % 5)) {
    $a .= "Buzz"
} elsif ($_ % 3) {
    $a = $_
}

print "$a\n"

}

Nothing special at all, just some fairly tight, clean code. Aside from the broken apart if block and the use of bad variable names ($a, $_) it wouldn’t look out of place in a normal program. After exhausting my knowledge of esoteric Perl, I whittled it down to this:

for (1..100) {
    $a = ($_ % 3) ? "" : "Fizz";
    $a .= "Buzz" if !($_ % 5);

1
2
3
$a ||= $_;

print "$a\n"

}

With a bit of digging, I found that I could use the + and , operators as part of print to get rid of that $a assignment:

for (1..100) {
    $a = ($_ % 3) ? "" : "Fizz";
    $a .= "Buzz" if !($_ % 5);

1
print + $a || $_, "\n"

}

But you certainly don’t need most of the parenthesis, and Perl deals with barewords just fine:

for (1..100) {
    $a = $_ % 3 ? "" : Fizz;
    $a .= Buzz if !($_ % 5);

1
print + $a || $_, "\n"

}

Finally, after reading through perlvar I found that the input record separator, which defaults to “\n”, can take the place of that four-character newline:

for (1..100) {
    $a = $_ % 3 ? "" : Fizz;
    $a .= Buzz if !($_ % 5);

1
print + $a || $_, $/

}

101 characters, but you can go a step further, drop the $a assignment and condense those statements down below:

for (1..100) {
    print + ($_ % 3 ? "" : Fizz) . ($_ % 5 ? "" : Buzz) || $_, $/
}

Finally, since this is now a single Perl statement, the curly braces can be eliminated by placing the loop control at the end (thanks to Fotios for that tip). After you beat the whitespace out, you end up with 56 characters:

print+($%3?"":Fizz).($%5?"":Buzz)||$_,$/for(1..100)

Q.E.D.