I am a web application developer by profession, spending my days as a beer-deprived “code monkey”. Oh, I love my job, but I probably do write better code after having a couple of beers.
In any event, it was with some delight that I recently re-discovered the 99 Bottles of Beer site. Subtitled “one program in 1064 1253 variations”.
Just about everyone above the age of ten is familiar with the lyrics to 99 Bottles of Beer on the wall. (Just in case you aren’t they do offer a helpful page with the lyrics.) This site collects snippets of program code that generate the lyrics in hundreds of programming languages. To whit:
10 REM Basic version of 99 bottles of beer
20 REM Modified by M. Eric Carr (eric@carrnet.net)
30 REM from prior version found on this site.
40 REM (Modified to correct "1 bottle" grammar)
50 FOR X=99 TO 1 STEP -1
60 PRINT X;"bottle";
70 IF X<>1 THEN PRINT "s";
80 PRINT " of beer on the wall,";X;"bottle";
90 IF X<>1 THEN PRINT "s";
100 PRINT " of beer"
110 PRINT "Take one down and pass it around,"
120 PRINT X-1;"bottle";
130 IF X<>1 THEN PRINT "s";
140 PRINT " of beer on the wall"
150 NEXT
or
// 99 bottles of beer, C++ template 'meta-programming' version
// By Arion Lei (philipl@cs.ust.hk)
#include <iostream.h>
template<int I>
class Loop {
public:
static inline void f () {
cout << I << " bottles of beer on the wall," << endl
<< I << " bottles of beer." << endl
<< "Take one down, pass it around," << endl
<< I-1 << " bottles of beer on the wall." << endl;
Loop<I-1>::f();
}
};
class Loop<0> {
public:
static inline void f () {
cout << "Go to the store and buy some more," << endl
<< "99 bottles of beer on the wall." << endl;
}
};
int main () {
Loop<3>::f();
return 0;
}
</iostream.h>
or
/**
* Java 5.0 version of the famous "99 bottles of beer on the wall".
* Note the use of specific Java 5.0 features and the strictly correct output.
*
* @author kvols
*/
import java.util.*;
class Verse {
private final int count;
Verse(int verse) {
count= 100-verse;
}
public String toString() {
String c=
"{0,choice,0#no more bottles|1#1 bottle|1<{0} bottles} of beer";
return java.text.MessageFormat.format(
c.replace("n","N")+" on the wall, "+c+".n"+
"{0,choice,0#Go to the store and buy some more"+
"|0<Take one down and pass it around}, "+c.replace("{0","{1")+
" on the wall.n", count, (count+99)%100);
}
}
class Song implements Iterator<Verse> {
private int verse=1;
public boolean hasNext() {
return verse <= 100;
}
public Verse next() {
if(!hasNext())
throw new NoSuchElementException("End of song!");
return new Verse(verse++);
}
public void remove() {
throw new UnsupportedOperationException("Cannot remove verses!");
}
}
public class Beer {
public static void main(String[] args ) {
Iterable<Verse> song= new Iterable<Verse>() {
public Iterator<Verse> iterator() {
return new Song();
}
};
// All this work to utilize this feature:
// "For each verse in the song..."
for(Verse verse : song) {
System.out.println(verse);
}
}
}
or
#!/usr/bin/perl
# Jim Menard jimm@{bbn,io}.com (617) 873-4326 http://www.io.com/~jimm/
$nBottles = $ARGV[0];
$nBottles = 100 if $nBottles eq '' || $nBottles < 0;
foreach (reverse(1 .. $nBottles)) {
$s = ($_ == 1) ? "" : "s";
$oneLessS = ($_ == 2) ? "" : "s";
print "n$_ bottle$s of beer on the wall,n";
print "$_ bottle$s of beer,n";
print "Take one down, pass it around,n";
print $_ - 1, " bottle$oneLessS of beer on the walln";
}
print "n*burp*n";
or
<cfscript>
function beerSong(x) {
b = iif(x gt 1, DE("bottles"), DE("bottle"));
if (x) {
WriteOutput("#x# #b# of beer on the wall...<br>#x# #b# of beer!</br>");
WriteOutput("Take one down, pass it around...<br>";
beerSong( x - 1 );
}
else
{
WriteOutput("No bottles of beer on the wall");
}
}
beerSong(99);
</cfscript>
and on…and on…and on…
Languages I’ve never even heard of are represented here. Just about every one also has several variations.
Beer fans who are also computer geeks will appreciate it, anyway.