{"id":66,"date":"2011-05-08T13:13:19","date_gmt":"2011-05-08T17:13:19","guid":{"rendered":"http:\/\/lorinhalpert.com\/blag\/?p=66"},"modified":"2022-03-20T20:08:28","modified_gmt":"2022-03-21T00:08:28","slug":"php-code-golf-fizzbuzz","status":"publish","type":"post","link":"http:\/\/lorinhalpert.com\/blag\/archives\/66","title":{"rendered":"PHP Code Golfing &#8211; &#8216;FizzBuzz&#8217;"},"content":{"rendered":"<p>Back in 2007 I read an <a href=\"http:\/\/www.codinghorror.com\/blog\/2007\/02\/why-cant-programmers-program.html\" target=\"_blank\" rel=\"noopener noreferrer external\" class=\"ext-link\">interesting article<\/a> about programmers who can&#8217;t actually program, probably shocking to some but not to those that remember <a href=\"http:\/\/en.wikipedia.org\/wiki\/Sturgeons_Law\" target=\"_blank\" rel=\"noopener noreferrer external\" class=\"ext-link\">Sturgeon&#8217;s Law<\/a> (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.<\/p>\n<p>The description of the program is as follows:<\/p>\n<blockquote><p>Write a program that prints the numbers from 1 to 100. But for multiples of three print &#8220;Fizz&#8221; instead of the number and for the multiples of five print &#8220;Buzz&#8221;. For numbers which are multiples of both three and five print &#8220;FizzBuzz&#8221;.<\/p><\/blockquote>\n<p>Soon thereafter I discovered the concept of &#8216;code golfing&#8217; 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 &#8211; some that might one day save a lot of grief. Thus my spiral into madness began as I set out to make the world&#8217;s smallest working version of the trivial FizzBuzz in PHP. Drinking <em>might<\/em> have been involved in this decision.<\/p>\n<p>Let&#8217;s begin with a clean example of FizzBuzz, coded in PHP, weighing in at 351 bytes:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">&lt;?php\n\/\/ Simple FizzBuzzer by Lorin\nfor ($num = 1; $num &lt;= 100; $num++) { \n    if ($num %3 === 0 || $num % 5 === 0) {\t\/\/ is $num divisible by 3 or 5?\n      if ($num % 3 === 0) echo 'Fizz';\t\/\/ Modulus instead of division\n      if ($num % 5 === 0) echo 'Buzz';\n    } else echo $num; \/\/ otherwise display number\n    echo PHP_EOL; \/\/ new line!\n}\n?&gt;<\/pre>\n<p>Ok, easily readable &#8211; works fine. Now let&#8217;s golf, but I&#8217;ll skip to the conclusion since that&#8217;s why you&#8217;re here, isn&#8217;t it?<\/p>\n<p>But before that, I&#8217;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 <a href=\"http:\/\/en.wikipedia.org\/wiki\/64k_intro\" class=\"ext-link\" rel=\"external\" target=\"_blank\">demo scene<\/a> 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.<\/p>\n<p>Here&#8217;s the svelte 56 byte result, a 6.2x decrease in code base!<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">&lt;?while($i++&lt;100)echo$i%3?!$i=$i:Fizz,$i%5?$i:Buzz,~\u00f5;<\/pre>\n<p>Let&#8217;s break down the code:<\/p>\n<ul>\n<li>Instead of the standard PHP opening tag, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">&lt;?php<\/code>, I use the much debated short tag opener <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">&lt;?<\/code>, which I personally prefer. Additionally opening short tags don&#8217;t require a trailing space or newline &#8211; saving 4 bytes. This option may not be enabled by default on your server.<\/li>\n<li>PHP doesn&#8217;t require a closing tag when it&#8217;s the final element outputted, so a semicolon is used instead, saving a single byte. Not including closing tags is actually <a href=\"https:\/\/www.php.net\/basic-syntax.instruction-separation\" class=\"ext-link\" rel=\"external\" target=\"_blank\">recommended<\/a> in some circumstances!<\/li>\n<li>All comments and whitespace are removed, and the variable is now a single character &#8211; we&#8217;re going for computer executability, not human readability.<\/li>\n<li>Shortening the loop &#8211; 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.<\/li>\n<li>Ternary operators instead of ifs. Because modulus operators return 0 when &#8216;true&#8217; I had to swap the functions. A previous, larger version utilized three stacked ternary operators it was painful to debug. Don&#8217;t stack ternary operators if you can help it.<\/li>\n<li>A variable set within echo&#8230; is echoed. However adding <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">!<\/code> makes it &#8216;falsey&#8217;, and therefore unechoed.<\/li>\n<li>Variable variables, the epicenter of madness. Variable variables may be named ANYTHING, even normally &#8216;illegal&#8217; 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&#8230;), 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&#8230;<\/li>\n<li>On servers with reduced warnings you may remove the quotes around &#8216;Fizz&#8217; and &#8216;Buzz&#8217;, using unset constants instead of strings. This will generate errors in future versions of PHP.<\/li>\n<li>What happened to the new line? It got bit flipped! Instead of <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">PHP_EOL<\/code> (7 bytes), <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\"\\r\\n\"<\/code> (6 bytes) or a physical new-line ascii character (3 bytes), I utilize the ~ bitwise operator, inverting the &#8216;\u00f5&#8217; character into the new-line character. This was the biggest &#8216;<em>AHA!<\/em>&#8216; moment for me. However it won&#8217;t work in UTF-8 encoded files, use ANSI encoding instead.<\/li>\n<\/ul>\n<p>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! :)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Back in 2007 I read an interesting article about programmers who can&#8217;t actually program, probably shocking to some but not to those that remember Sturgeon&#8217;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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,41,18],"tags":[],"class_list":["post-66","post","type-post","status-publish","format-standard","hentry","category-code","category-hacks","category-projects"],"_links":{"self":[{"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/posts\/66","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/comments?post=66"}],"version-history":[{"count":0,"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/posts\/66\/revisions"}],"wp:attachment":[{"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/media?parent=66"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/categories?post=66"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/lorinhalpert.com\/blag\/wp-json\/wp\/v2\/tags?post=66"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}