tags:

views:

518

answers:

3

*EDIT: since some folk's panties are apparently bunching uncomfortably over this, how about just recommending some efficient ways of dealing with similar code? Maybe not specific answers to the problem I posed (my goal anyway, this bit of code golf was merely a means to finding more concise ways of dealing with the basic problems presented), rather, general suggestions for ways to optimize/shorten things dealt with by this question? As I said...

This is just meant to be fun (and if you are a l337 programmer who is offended by such noobish questions... well, tough)!

I found a PHP programming puzzle online that asks you to solve a problem as efficiently as possible. The problem is to print the "99 Bottles of Beer on the Wall" song using as little code as possible. The required lines are:

99 bottles of beer on the wall, 99 bottles of beer.
Take 1 down, pass it around, 98 bottles of beer on the wall.

98 bottles of beer on the wall, 98 bottles of beer.
Take 1 down, pass it around, 97 bottles of beer on the wall.

etc, etc, on down to...

1 bottle of beer on the wall, 1 bottle of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.

The best I could manage was not very good compared to some other solutions I found. Basically, you want to solve it in the fewest bytes possible. I did it in about 260 bytes. I saw someone else that did it in a mere 187. What I'm interested in finding out here is... how did he/she do it?!

I will print my solution here for reference and to prove that I did it (and I'm not asking for a homework solution, lol) but I am very curious as to how one would optimize the solution to use as few bytes as possible (fyi my solution could shave a few bytes by not using newlines but I want it to be as readable as possible here).

<?php
$a="beer on the wall";
for($i=99;$i>=1;$i--){
$x=($i==1)?"bottle":"bottles";
$b="<p>$i $x of $a, $i $x of beer.<br>";
$b.=($i==1)?"Go to the store and buy some more, 99 bottles of $a.":"Take one down and pass it around, ".($i-1)." $x of $a.</p>";
echo $b;
}

Oh, you can get the number of bytes by creating the file and then running:

ls -l /location/of/the/dir/containing/the/file/

A: 

How about:

<?php echo file_get_contents('http://goo.gl/zksB'); ?>

=P

Kranu
+1  A: 

Inspired by the people who linked to the solution... this code actually works (if allow_url_fopen and allow_url_include are turned on):

<?include('http://3.ly/9PSC');

30 bytes

captaintokyo
+3  A: 

For those that are curious, this is a problem that has shown up on codegolf.com previously and on phpGolf.org more recently. That said, I've managed to get the code down to 184 characters in php, so I figured I'd give a few tips on how I would improve your solution:

  • You don't need to use <?php. Instead just use <?
  • Using $a to replace the repetitive text is a good call, but every time you use $a, you have the word 'of' before it. It might make sense to add it to $a. You could also play around with breaking the strings $a, $b, and $x up in different ways
  • Your clause to deal with the difference between bottle and bottles can be shortened significantly. At the very least, don't repeat the characters in 'bottle' twice.
  • You don't need the <p> and <br> formatting. In fact, even using a \n would be one too many characters. Just use an actual newline in your code.
  • Don't use characters when you don't need them. More specifically, when you have stuff like $x=($i==1)..., the ( and ) are unnecessary.
  • You can save a couple characters by getting rid of the $i-- in your for loop and adding a -- to your last $i==1. Then you also wouldn't need to subtract 1 from $i later in the line.

Hopefully some of these suggestions will help you get started in shaving off the bytes.

zkhr