PHP Code Golfing – ‘FizzBuzz’
May 8th, 2011 - 1:13 pm | 2 Comments | Code, Hacks, ProjectsBack in 2007 I read an interesting article about programmers who can’t actually program, probably shocking to some but not to those that remember Sturgeon’s Law (90% of everything is crap). A quick glance at the program described and I already had the code floating around in my head, trivial for a seasoned programmer.
The description of the program is as follows:
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
Soon thereafter I discovered the concept of ‘code golfing’ and was intrigued. I quickly rationalized that it was the best ways to teach bad coding practices, but at the same time give invaluable insight into the infrequently used operations of the language – some that might one day save a lot of grief. Thus my spiral into madness began as I set out to make the world’s smallest working version of the trivial FizzBuzz in PHP. Drinking might have been involved in this decision.
Let’s begin with a clean example of FizzBuzz, coded in PHP, weighing in at 351 bytes:
<?php // Simple FizzBuzzer by Lorin for ($num = 1; $num <= 100; $num++) { if ($num %3 === 0 || $num % 5 === 0) { // is $num divisible by 3 or 5? if ($num % 3 === 0) echo 'Fizz'; // Modulus instead of division if ($num % 5 === 0) echo 'Buzz'; } else echo $num; // otherwise display number echo PHP_EOL; // new line! } ?>
Ok, easily readable – works fine. Now let’s golf, but I’ll skip to the conclusion since that’s why you’re here, isn’t it?
But before that, I’d like to note code that looks like the following rarely has any reason to exist other than being a personal challenge. The two major exceptions to this would be demo scene code, where the goals are quite similar to those of code golf, or where code space is at an extreme premium, which has become much less relevant these days.
Here’s the svelte 56 byte result, a 6.2x decrease in code base!
<?while($i++<100)echo$i%3?!$i=$i:Fizz,$i%5?$i:Buzz,~õ;
Let’s break down the code:
- Instead of the standard PHP opening tag,
<?php
, I use the much debated short tag opener<?
, which I personally prefer. Additionally opening short tags don’t require a trailing space or newline – saving 4 bytes. This option may not be enabled by default on your server. - PHP doesn’t require a closing tag when it’s the final element outputted, so a semicolon is used instead, saving a single byte. Not including closing tags is actually recommended in some circumstances!
- All comments and whitespace are removed, and the variable is now a single character – we’re going for computer executability, not human readability.
- Shortening the loop – this was the easiest of all the shorthands tricks which I use when banging out proof of concept code. It loops from 1 to 100, a neat off-by-one effect.
- Ternary operators instead of ifs. Because modulus operators return 0 when ‘true’ I had to swap the functions. A previous, larger version utilized three stacked ternary operators it was painful to debug. Don’t stack ternary operators if you can help it.
- A variable set within echo… is echoed. However adding
!
makes it ‘falsey’, and therefore unechoed. - Variable variables, the epicenter of madness. Variable variables may be named ANYTHING, even normally ‘illegal’ variable names made up from numerals only. This means every time the code loops it not only does it create a new variable named after its own value ($1, $2, $3…), but it also consumes additional memory. This took me the longest to figure out and was only discovered with the help of a peer. Nightmarish stuff…
- On servers with reduced warnings you may remove the quotes around ‘Fizz’ and ‘Buzz’, using unset constants instead of strings. This will generate errors in future versions of PHP.
- What happened to the new line? It got bit flipped! Instead of
PHP_EOL
(7 bytes),"\r\n"
(6 bytes) or a physical new-line ascii character (3 bytes), I utilize the ~ bitwise operator, inverting the ‘õ’ character into the new-line character. This was the biggest ‘AHA!‘ moment for me. However it won’t work in UTF-8 encoded files, use ANSI encoding instead.
So there you have it, the smallest version of FizzBuzz possible in PHP, although I look forward to a day where it gets beat. No cheating by loading from external sources! :)
↑ Join the Discussion (2)Solving the Music Player Refresh bug (Symbian S60)
May 29th, 2010 - 6:17 pm | No Comments | Audio, Code, Hacks, Modifications, ProjectsHow many times has this happened to you on your Nokia phone? You take out your MicroSDHC card and toss all your MP3s on to it… put it into the phone, Music Player begins to refresh and… Freezes. Well, the bar is still moving but your refresh counter is either stuck at zero or some other number that is much less than the actual amount of music you added. This was a permanent error and required you to delete your media database to allow it to reload any new media ever again.
This upset me greatly and it seems like no one online had a clue to it’s cause or how to fix it; So, I set out to do what Nokia should have done ages ago and debugged/solved it myself!
WHY IT BREAKS
There is a bug within a hidden system service called MPXHarvesterServer. Its mission is to update the media database if any new or changed media show up on the phone. Â My current theory is this: If the harvester hits an MP3 file with either desynchronized ID3v1 and v2 tags, general ID3 corruption or “non-standard” tags hacks on an otherwise playable track it just suicides and corrupts the media database. It could also be that the MPX harvester server just doesn’t like anything but ID3v2.3 and chokes/dies on 1.1/2.2/2.4 tags.
HOW TO FIX IT
- Use software such as MediaMonkey (FREE!) to repair/resyncronize ID3 tags on your PC before synchronizing or copying to phone. The ghetto method of doing this is to select your whole music library and then edit one of the normally unused ID3v2 tags, such as ISRC or custom elements so it forces a complete redo of the ID3 tags on the files.
- Erase the potentially corrupted  database. Take your MicroSDHC card and connect it directly to the computer so you can delete the following files:
- “mpxv1.mpd” and “pcv5.mpd” inside the \private\101FFC31\ directory
- “harvesterdb.dat” inside the \private\101ffca9 directory
- Put the card back into your phone and enjoy a complete Music Player experience :)
If you happen to work for Nokia/Symbian: Please add at least a bit of error resistance/fallback. While your there make it so the music player only scans for music in the */music/ folders and not my ringtones or recorded messages directories, thanks.
↑ Post a Comment