63
votes
\$\begingroup\$

Recreate '99 bottles of beers on the wall'.

The desired output is this:

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

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

97 bottles of beer on the wall, 97 bottles of beer.
Take one down and pass it around, 96 bottles of beer on the wall.

96 bottles of beer on the wall, 96 bottles of beer.
Take one down and pass it around, 95 bottles of beer on the wall.

95 bottles of beer on the wall, 95 bottles of beer.
Take one down and pass it around, 94 bottles of beer on the wall.

....

3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.

2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

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.

Show me how you would solve this with your favorite programming language. Most creative use of a language wins.

\$\endgroup\$
12
  • 30
    \$\begingroup\$ "Most creative use" is too subjective for an SE site, I think. We should aim to use objective criteria, such as "shortest code". \$\endgroup\$ Jan 27, 2011 at 21:04
  • 5
    \$\begingroup\$ Still a good question though \$\endgroup\$ Jan 27, 2011 at 21:06
  • 3
    \$\begingroup\$ Is it supposed to run infinitely? I assumed so. Also codegolf doesn't own 99 bottles of beer so there is not reason to even discuss it. \$\endgroup\$
    – Mike Bethany
    Jan 28, 2011 at 8:04
  • 1
    \$\begingroup\$ @Chris -- That is going to be the toughest part of this SE site, because the whole thing is based on creativity, because that is half the fun of programming puzzles. The most creative solution isn't always the most efficient or shortest. \$\endgroup\$ Jan 28, 2011 at 14:13
  • 2
    \$\begingroup\$ @Nick: I hear you. I just want to know how one can determine how creative a solution is---based on your own judgement? Based on the voters'? Neither is particularly reliable (no offence). Something like brevity is indisputable---for example, nobody can dispute the "goodness" of the 1-byte stack overflow code golf solution. \$\endgroup\$ Jan 28, 2011 at 14:26

117 Answers 117

1
vote
\$\begingroup\$

C++

#include<iostream>

using namespace std;

int f(int n)
{
    if(!(n-1))
    { 
        cout<<"Take one down and pass it around, 1 bottle of beer on the wall."<<endl<<endl;

        cout<<"1 bottle of beer on the wall, 1 bottle of beer."<<endl;
        cout<<"Go to the store and buy some more, 99 bottles of beer on the wall."<<endl<<endl; 
        return 0;
    }

    n!=99 && cout<<"Take one down and pass it around, "<<n <<" bottles of beer on the wall."<<endl<<endl;
    cout<<n<<" bottles of beer on the wall, "<< n<< " bottles of beer. "<<endl;

    return f(--n);
}   

int main()
{
    f(99);
    return 0;
}
\$\endgroup\$
1
vote
\$\begingroup\$

QBasic - Runs in MS-DOS 6.22

DATA "abdefghiklmnoprstuwy ,."
DATA 6,2,4,1,1,2,3,4,4,3,4,3,4,2,6,2,2,5,3,4,4,1,1
DATA 2,13,17,17,10,4,13,5,2,4,4,15,21,16,13,12,17,7,4,19,1,10,10,-17,1,9,4,13,12,4,3,13,19,12,1,12,3,14,1,16,16,8,17,1,15,13,18,12,3,-6,13,17,13,16,17,13,15,4,2,18,20,16,13,11,4,11,13,15,4,22,23
DATA 7,6,6,13,15,1,1
DATA 4,1,5,4,2,4,3
DATA 4,1,4,2,4,3
DATA 4,6,4,7,4,8
DATA 9,4,10,4,11,4,12,4,13,4,14,4,15
DATA 16,4,17,4,7,4,18,4,12,4,19,4,20,4,21
DATA 22
DATA 23

READ l$
DIM z$(LEN(l$))
DIM x%(LEN(l$))
DIM u%(7)
m% = 1

FOR y% = 1 TO UBOUND(x%)
        READ x%(y%)
NEXT y%

FOR y% = 1 TO 6
        m% = m% * x%(y%)
NEXT y%

m% = m% + x%(y%)

FOR y% = 1 TO UBOUND(z$)
        FOR w% = 1 TO x%(y%)
                READ v%
                IF v% > 0 THEN
                        z$(y%) = z$(y%) + MID$(l$, v%, 1)
                ELSE
                        z$(y%) = z$(y%) + UCASE$(MID$(l$, -1 * v%, 1))

                END IF
        NEXT w%
NEXT y%

FOR y% = 1 TO UBOUND(u%)
        READ u%(y%)
NEXT y%

FOR y% = 1 TO UBOUND(u%)
        FOR w% = 1 TO u%(y%)
                READ v%
                s$(y%) = s$(y%) + z$(v%)
        NEXT w%
NEXT y%

FOR i% = m% TO 1 STEP -1

        IF i% > 2 THEN
                PRINT STR$(i%) + s$(1) + s$(3) + s$(6) + STR$(i%) + s$(3) + s$(7)
                PRINT s$(4) + s$(6) + STR$(i% - 1) + s$(1) + s$(3) + s$(7)
        ELSEIF i% = 2 THEN
                PRINT STR$(i%) + s$(1) + s$(3) + s$(6) + STR$(i%) + s$(1) + s$(7)
                PRINT s$(4) + s$(6); STR$(i% - 1) + s$(2) + s$(3) + s$(7)
        ELSE
                PRINT STR$(i%) + s$(2) + s$(3) + s$(6) + STR$(i%) + s$(2) + s$(7)
                PRINT s$(5) + s$(6) + STR$(m%) + s$(1) + s$(3) + s$(7)
        END IF

        PRINT ""
NEXT i%
\$\endgroup\$
1
vote
\$\begingroup\$

LaTeX / PGF

Using (almost) only the new logic facilities of the PGF/TikZ project:

\documentclass[twocolumn]{article} % Use twocolumn option to ... um ... save paper
\usepackage{tikz}
\usepackage{fmtcount}

\begin{document}
\pgfkeyssetvalue{/singular/0}{s}
\pgfkeyssetvalue{/singular/1}{}

\pgfkeys{/text/1/.code={\numberstringnum{#1}}}
\pgfkeys{/text/0/.code={no more}}

\foreach \x in {99, 98 , ..., 1} {
  \pgfmathequalto{\x}{1}
  \noindent
  \Numberstringnum{\x} bottle\pgfkeys{/singular/\pgfmathresult} of beer of the wall,\\
  \numberstringnum{\x} bottle\pgfkeys{/singular/\pgfmathresult} of beer.\\
  Take one down pass it around,\\
  \pgfmathtruncatemacro{\y}{\x - 1}
  \pgfmathgreaterthan{\y}{0}
  \pgfkeys{/text/\pgfmathresult=\y}\pgfmathequalto{\y}{1}
    bottle\pgfkeys{/singular/\pgfmathresult} of beer on the wall.\\
  \\
}

\end{document}
\$\endgroup\$
2
  • \$\begingroup\$ that language seems pretty hard to write, to do "\" in my keyboard I must click ctrl + alt + <another key> \$\endgroup\$
    – ajax333221
    Mar 26, 2012 at 23:41
  • \$\begingroup\$ I don't know about your keyboard, but no, doing logic in LaTeX is not simple. \$\endgroup\$ Mar 27, 2012 at 4:17
1
vote
\$\begingroup\$

Not the shortest, but an attempt to use the most extraordinary Duff's Device.

#include <stdio.h>

void print_beer(int *n)
{
    printf("%d bottles of beer on the wall, %d bottles of beer.\n", *n, *n);
    --*n;
    printf("Take one down and pass it around, %d bottle%s of beer on the wall.\n\n", *n, *n > 1 ? "s" : "");
}

void beer(int n)
{
    switch (((n - 1)) % 7) {
        case  0:   do { print_beer(&n);
        case  6:        print_beer(&n);
        case  5:        print_beer(&n);
        case  4:        print_beer(&n);
        case  3:        print_beer(&n);
        case  2:        print_beer(&n);
        case  1:        print_beer(&n);
                   } while (n - 6 > 0);
    }
}

int main(void)
{
    int n = 99;

    beer(n);
    printf("1 bottle of beer on the wall, 1 bottle of beer.\n");
    printf("Go to the store and buy some more, %d bottles of beer on the wall.\n", n);

    return 0;
}
\$\endgroup\$
1
vote
\$\begingroup\$

Q, 245

{-1(-3!x),b,$[x=1;e;d],a,", ",(-3!x),b,$[x=1;e;d]," of beer.\n",$[x=1;"Go to the store and buy some more, ";"Take one down and pass it around, "],(-3!$[x=1;99;x-1]),(b:" bottle"),$[x=2;e:"";d:"s"],(a:" of beer on the wall"),".";}each(99-til 99);
\$\endgroup\$
1
vote
\$\begingroup\$

PHP - 176

My implementation has some null bytes or other random "?" characters, so I wrote a wrapper around it to show how to get the string, as well as the total characters output:

$string = gzdeflate('$a=" bottle";$b=" of beer";$c=" on the wall";for($i=99;$i>1;)echo"$i{$a}s$b$c, $i{$a}s$b.\nTake one down and pass it around, ".--$i.$a."s$b$c.\n\n";echo"$i$a$b$c, $i$a$b.\nGo to the store and buy some more, 99{$a}s$b$c.";');
$total  = strlen($string);
$total += strlen("eval(gzinflate(''))");

echo 'Total characters: '.$total."\n\n\n";
eval(gzinflate($string));
\$\endgroup\$
1
vote
\$\begingroup\$

JAVA (353)

public static void main(String[] args) {
    String s[] = new String[]{"s", "", "Take one down and pass it around, %d bottle%s of beer on the wall.\n", "Go to the store and buy some more, 99 bottles of beer on the wall\n"};
    for (int i=1; i<100;) System.out.println(String.format("%d bottle%s of beer on the wall, %d bottle%s of beer.\n%s", 100-i, s[i/99], 100-i, s[i++/99], String.format(s[i/100+2], 100-i, s[i/99])));
}
\$\endgroup\$
1
vote
\$\begingroup\$

Java (543 Characters)

Here is my attempt at this challenge.

public class BottlesOfBear {

    public static void main(String[] args) {

        final int BOTTLEAMOUNT = 99;
        int bottleCount = 99;

        for (int i = 0; i < BOTTLEAMOUNT; i++) {
            System.out.println(bottleCount + (bottleCount == 1 ? " bottle " : " bottles ") + "of beer on the wall, " + bottleCount + (bottleCount == 1 ? " bottle " : " bottles ") + "of beer.");
            bottleCount--;
            System.out.println("Take one down and pass it around, " + bottleCount + (bottleCount == 1 ? " bottle " : " bottles ") + "of beer on the wall.");
        }

    }

}
\$\endgroup\$
1
vote
\$\begingroup\$

PHP (225 chars)

<?=preg_replace('/\w/e','$0=="b"?"$n bottle".($n>1?"s":"")." of beer":($0=="w"?"on the wall":(--$n?"Take one down and pass it around":(($n=99)?"Go to the store and buy some more":"")))',str_repeat('b w, b.
t, b w.

',$n=99));
\$\endgroup\$
1
vote
\$\begingroup\$

C++

Uses recursion.

#include <iostream>
using namespace std;
void f(int n)
{
    if(n==0)
    {
        cout<<"Go to the store and buy some more, 99 bottles of beer on the wall.";
    }
    else
    {
        if(n==94)cout<<"....\n\n";
        else if(n>94||n<4)
            cout<<n<<" bottles of beer on the wall, "<<n<<" bottles of beer.\nTake one down and pass it around, "<<n-1<<" bottles of beer on the wall.\n\n";
        f(n-1);
    }
}
int main()
{
f(99);
return 0;
}
\$\endgroup\$
1
vote
\$\begingroup\$

Python 2.x - (306 293 288 bytes)

So, this is was an older script of mine. It is a one-liner and heavily golfed. Demo

print(lambda x:x(x,99,lambda c,w=1,p=0:"%s %s of beer%s"%(c or"nN"[p]+"o more","bottle"+"s"*(c!=1)," on the wall"*w)))(lambda x,c,y:c+1and"%s, %s.\n%s"%(y(c,1,1),y(c,0),"Take one down and pass it around, %s.\n\n"%y(c-1)*(c>0))+x(x,c-1,y)or"Go to the store and buy some more, %s.\n"%y(99))

293 bytes version

print(lambda x:x(x,99,lambda c,w=1,p=0:"%s %s of beer%s"%(c or("n","N")[p]+"o more","bottle"+"s"*(c!=1)," on the wall"*w)))(lambda x,c,y:c+1and"%s, %s.\n%s"%(y(c,1,1),y(c,0),"Take one down and pass it around, %s.\n\n"%y(c-1)*(c>0))+x(x,c-1,y)or"Go to the store and buy some more, %s.\n"%y(99))

306 bytes version

print(lambda x:x(x,99,lambda c,w=1,p=0:"%s %s of beer%s"%(c or("n","N")[p]+"o more","bottle"+("s","")[c==1],(""," on the wall")[w])))(lambda x,c,y:c+1and"%s, %s.\n%s"%(y(c,1,1),y(c,0),c and"Take one down and pass it around, %s.\n\n"%y(c-1)or"")+x(x,c-1,y)or"Go to the store and buy some more, %s.\n"%y(99))

Fixing it for Python 3 would add two characters (untested):

print((lambda x:x(x,99,lambda c,w=1,p=0:"%s %s of beer%s"%(c or"nN"[p]+"o more","bottle"+"s"*(c!=1)," on the wall"*w)))(lambda x,c,y:c+1and"%s, %s.\n%s"%(y(c,1,1),y(c,0),"Take one down and pass it around, %s.\n\n"%y(c-1)*(c>0))+x(x,c-1,y)or"Go to the store and buy some more, %s.\n"%y(99)))

I would like to note that it isn't exactly elegant. To change the starting amount, you would need to change both occurences of 99 (one at the beginning and one at the end).

Edit: I think I should explain how it works. I circumvent the fact that I can't recurse a function if it's not named by creating an anonymous function, which takes an anonymous function as a parameter and calls it, passing it as an argument. Then it's just string formatting and neat little if-clauses built by using tuples and selecting the value with a boolean. Furthermore, I used c or "no more" to select c if it's greater than 0 and otherwise "no more".

Edit 2: Seems like I missed some pretty big things like multiplying strings with booleans instead of ("","text")[bool] and the fact that strings are iterable (("n","N")[p] -> "nN"[p])

\$\endgroup\$
1
vote
\$\begingroup\$

C++

Why output to the console when you can output error messages?

main.cpp:

#include "99.h"
int main(){return 0;}

99.h:

#error 99 bottles of beer on the wall...
#include "98.h"

98.h:

#error 98 bottles of beer on the wall...
#include "97.h"

This is continued all the way through 1.h:

#error 1 bottle of beer on the wall...

When the programmer tries to compile it, the compiler outputs the error message

99 bottles of beer on the wall...

The programmer then removes the #error statement and recompiles the program, getting the error message

98 bottles of beer on the wall...

Eventually this outputs the entire song.

\$\endgroup\$
1
vote
\$\begingroup\$

node/javascript - 180

b=' bottles of beer';w=' on the wall';i=99;while(i)console.log(i+b+w+', '+i+b+'\n'+(!--i?'Go to the store and buy some more, 99':'Take one down and pass it around, '+i)+b+w+'.\n');
\$\endgroup\$
2
  • \$\begingroup\$ Could you add an explanation/an ungolfed version, please? \$\endgroup\$ Nov 5, 2015 at 19:54
  • 2
    \$\begingroup\$ Golfing tip: never use while(cond). It's the same length as for(;cond;), and you can nearly always take advantage of moving something into the initialisation and something into the update parts of the for to save at least one character each for a semicolon. \$\endgroup\$ Nov 5, 2015 at 21:31
0
votes
\$\begingroup\$

MS Excel (14,683bytes)

MS Excel 2003, saved in .xlsx format (14,683 bytes) (is this really "programming") https://www.dropbox.com/s/40v2byau92ifka9/99bottles4.xlsx

\$\endgroup\$
1
  • \$\begingroup\$ "is this really "programming"" - no, unless you used VBA to fill out the data :) \$\endgroup\$ Aug 4, 2011 at 16:53
0
votes
\$\begingroup\$

Erlang - 326

-module(d).
-export([b/1]).
b(1)->io:format("1 bottle of beer on the wall, 1 bottle of beer.~nGo to the store and buy some more, 99 bottles of beer on the wall."),b(99);b(B)->C=B-1,io:format("~p bottles of beer on the wall, ~p bottles of beer.~nTake one down and pass it around, ~p bottles of beer on the wall.",[B,B,C]),b(C).
\$\endgroup\$
0
votes
\$\begingroup\$

PHP - first time there :)

<?php

$b = "bottles of beer";
$bw = "$b on the wall";
$t = "Take one down and pass it around,";
$cnt = 99;

     while(true)
     {
        echo "$cnt $bw, $cnt $b.\n";
        $cnt--;
        if ($cnt==0) break;
        echo "$t $cnt $bw.\n\n";
     }

     echo "Go to the store and buy some more, 99 $bw.\n\n";

?>
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 1 bottles of beer on the wall? \$\endgroup\$
    – boothby
    Jul 18, 2011 at 20:32
0
votes
\$\begingroup\$

Here. First time post. JAVA

public static void main(String [] args){
for(int i = 99; i>=2; i--){

    System.out.println(i + " bottles of beer on the wall, "+i+" bottles of beer. "
            + "\n Take one down and pass it around, "+(i-1)+" bottles of beer on the wall.\n");

}
 System.out.println("1 bottle of beer on the wall, 1 bottle of beer."
                   + " \n Go to the store and buy some more, 99 bottles of beer on the wall.");
}
\$\endgroup\$
0
votes
\$\begingroup\$

PHP (172)

for($i=99;$i>0;$i--){$s=($i>0)?'s':'';echo "$i bottle$s of beer on the wall, $i bottle$s of beer.\nTake one down and pass it around, $i bottle$s of beer on the wall.\n\n";}
\$\endgroup\$
0
votes
\$\begingroup\$

C# (271 Characters)

class P{static void Main(){string b=" bottle",w=" on the wall",o=" of beer",p=".\n",z;for(int i=99;i>0;)System.Console.Write((z=i+b+(i>1?"s":"")+o)+w+", "+z+p+(i-->1?"Take one down and pass it around, "+i:"Go to the store and buy some more, 99")+b+(i>1?"s":"")+o+w+p);}}
\$\endgroup\$
0
votes
\$\begingroup\$

Delphi (349)

program B;{$APPTYPE CONSOLE}const c=' of beer on the wall';d:array[Boolean]of string=(' bottles', ' bottle');var i:Byte;begin for i:=99downto 1do begin WriteLn(i,d[i=1],c,', ',i,d[i=1],' of beer.');if i>1then WriteLn('Take one down and pass it around, ',i-1,d[i<3],c,'.'#13#10)else Write('Go to the store and buy some more, 99',d[1=2],c,'.')end;end.
\$\endgroup\$
0
votes
\$\begingroup\$

Python 3 (not really golfed, just a bit creative)

b=lambda n:'%d bottl%s of beer'%(n,n>1and'es'or'e')
any(map(print,(((2*'%s, %s on the wall, %s.\n')[4:42]+'.\n')%(2*(b(i),)+(i>1and('Take one down and pass it around',b(i-1))or('Go to the store and buy some more',b(99))))for i in range(99,0,-1))))
\$\endgroup\$
0
votes
\$\begingroup\$

PHP 132 chars =]

    $e='bottles of beer';$x='on the wall';$i=100;while($i>0)echo"$i $e $x, $i $e.
Take one down and pass it around,  ".--$i." $e $x.

";
\$\endgroup\$
2
  • \$\begingroup\$ Go to the store and buy some more, 99 bottles of beer on the wall.? \$\endgroup\$
    – Gareth
    Oct 22, 2011 at 10:16
  • \$\begingroup\$ I didn't read that until it was too late =[ \$\endgroup\$ Oct 24, 2011 at 13:20
0
votes
\$\begingroup\$

C# - 324

using System;class b{ static void Main(){for(int i=99;i>1;i--){Console.WriteLine("{0} bottles of beer on the wall, {0} bottles of beer,\n"+"take one down, pass it around...\n", i);}Console.WriteLine("1 bottle of beer on the wall, 1 bottle of beer,\n"+"go to the store and buy some more, 99 bottles of beer on the wall!");}}
\$\endgroup\$
0
votes
\$\begingroup\$

C# - 304 significant characters.

Left this way to make it a little bit more readable, but it is 304 when all non-essential whitespace is removed.

string[] s = { "{0} {2}{3} {5}{6}, {0} {2}{3} {5}.\n", 
               "Take one down, pass it around, {1} {2}{4} {5}{6}.\n", 
               "Go to the store and buy some more, 99 {2}{4} {5}{6}." };
Func<int, string> t = e => e !=1 ? "s" : "" ;
for (int i = 99; i > 0; i--)
    Console.WriteLine(
         s[0] + s[i > 1 ? 1 : 2], 
         i, i - 1, 
         "bottle", t(i), t(i-1), "of beer", " on the wall");
\$\endgroup\$
0
votes
\$\begingroup\$

PYTHON

for x in xrange(99,0,-1):
    print('.\n\n'.join(('%(b)s on the wall',)*(2-x/99))+', %(b)s.\n%(c)s')%{'b':'%s bottle%s of beer'%(x,x-1 and's'or ''),'c':('Take one down, pass it around,','Go to the store and buy some more, 99 bottles of beer on the wall.')[(100-x)/99]},
\$\endgroup\$
0
votes
\$\begingroup\$

My PHP implementation:

<?php
$i = 99;
$s = '{i} bottles of beer on the wall';
$r = 'Take one down and pass it around';
$f = 'Go to the store and buy some more';

while($i > 0) 
{    
    $sub = array('{i}' => &$i);

    if($i == 1)
        $sub['bottles'] = 'bottle';

    $sen = strtr($s, $sub);
    echo $sen, ', ', substr($sen, 0, strpos($sen, 'on')), PHP_EOL;

    if($i == 1)
        break;

    $i--;
    $sen = strtr($s, $sub);
    echo $r, ', ', $sen, PHP_EOL, PHP_EOL;
}    

$i = 99;
$sub = array('{i}' => $i); 
$sen = strtr($s, $sub);
echo $f, ', ', $sen, PHP_EOL;
?>   
\$\endgroup\$
0
votes
\$\begingroup\$

Ruby 1.9.2p0 -- 208 C

b="%d bottle%s of beer";99.downto(1){|n|s=b%[n,n>1?'s':''];a=n-1;puts s+" on the wall, "+s+(n>1?"\nTake one down and pass it around,#{b%[a,a>1?'s':'']}":"\nGo to the store and buy some more, #{b%[99,'s']}.")}
\$\endgroup\$
0
votes
\$\begingroup\$

Ocaml - Hope this counts as creative

open Printf

let display () =
   let language = ref 99 in
   let ocaml = "bottles of beer on the the wall, " in
   let joy = " bottles of beer." in
   let usage = "Take one down and " in
   let is = "pass it around, " in
   let recommended = " bottles of beer on the wall." in
   let what = "bottle of beer on the wall, " in
   let like = "bottle of beer." in
   let applauded = " bottle of beer on the wall." in
   while (!language > 1) do
      let say = (string_of_int !language) in
      let strongly = (string_of_int (!language - 1)) in
      printf "%s %s %s %s\n" say ocaml say joy;
      if (!language > 2) then
         printf "%s %s %s %s\n" usage is strongly recommended
      else 
         printf "%s %s %s %s\n" usage is strongly applauded;
      language:= !language - 1;
   done;
   let say = (string_of_int !language) in
   let the_end = "Go to the store and buy some more, 99 bottles of beer on the wall." in
   printf "%s %s %s %s\n" say what say like;
   printf "%s\n" the_end
\$\endgroup\$
0
votes
\$\begingroup\$

Javascript (234)

o=' bottle',b=' of beer',s=o+'s'+b,w=' on the wall',t='.\nTake one down and pass it around, ',g='.\nGo to the store and buy some more, ',c=', ',i=99,n=i+s;while(i>1)print(n+w+c+n+t+(n=--i+o+[i>1?'s':'']+b));print(n+w+c+n+g+99+s+w+'.')

There is probably a way to reduce even further by avoiding the double print.

\$\endgroup\$
0
votes
\$\begingroup\$

CoffeeScript - 233

CoffeeScript is a bit hard to minify, but it's not bad:

b=' bottle';r=' of beer';w=' on the wall';t='Take one down and pass it around, ';g='Go to the store and buy some more, ';c=', ';i=100;x=1;(d=->x=--i+b+['s'if i>1]+r)();print x+w+', '+x+'\n'+(i>1&&t+d()+'\n'||--i||g+99+b+'s'+r)while i
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.