Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

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.

share|improve this question
17  
"Most creative use" is too subjective for an SE site, I think. We should aim to use objective criteria, such as "shortest code". – Chris Jester-Young Jan 27 '11 at 21:04
4  
Still a good question though – SimpleCoder Jan 27 '11 at 21:06
1  
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. – Mike Bethany Jan 28 '11 at 8:04
1  
@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. – Nick Berardi Jan 28 '11 at 14:13
2  
@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. – Chris Jester-Young Jan 28 '11 at 14:26
show 4 more comments

80 Answers

1 2 3

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);}}
share|improve this answer

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.
share|improve this answer

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))))
share|improve this answer

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.

";
share|improve this answer
show 2 more comments

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!");}}
share|improve this answer

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");
share|improve this answer

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]},
share|improve this answer

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;
?>   
share|improve this answer

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']}.")}
share|improve this answer

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
share|improve this answer

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);
share|improve this answer

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.

share|improve this answer

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
share|improve this answer

VB11 (Creative Version)

Imports System.Runtime.CompilerServices
Module BottleSong
 Sub Main()
 Console.WriteLine(<Song>
<%= Iterator Function()
For i=99 To 0 Step -1:Yield i:Next
End Function().Select(Function(Bottles)<Verse>
<%= Bottles.OfBeer %> on the wall, <%= Bottles.OfBeer %>.
<%= If(Bottles > 0, "Take one down and pass it around", "Go to the store and buy some more") %>.
<%= (Bottles - 1).OfBeer %> on the wall,<%= (Bottles - 1).OfBeer %>.

</Verse>)%></Song>.Value)
 End Sub

<Extension()>Public Function OfBeer(Bottles As Integer) As XNode
    Bottles = If(Bottles < 0, 99, Bottles)
    Return <Bottles><%= Bottles %> bottle<%= If(Bottles <> 1, "s", "") %> of Beer</Bottles>
End Function
End Module

Exploiting some of vb.net features.

  • XML LIterals
  • Iterator Lambda
  • Extension Method
share|improve this answer

AS2 - 159

a=99
b=" bottles of beer"
c=" bottle of beer"
d=" on the wall,"
e=", take one down and pass it around,"
while(a>0)
{
f=e+(a-1)+b+d
g=d+a
if(a<2)
    trace(a + c + g + c + f)
else
    trace(a + b + g + b + f)
--a
}

AS2 - 158 - Trimmed one off with a new if statement

a=99
b=" bottles of beer"
c=" bottle of beer"
d=" on the wall,"
e=", take one down and pass it around,"

while(a>0)
{
f=e+(a-1)+b+d
g=d+a
if(a<2?trace(a + c + g + c + f):trace(a + b + g + b + f));
--a
}

AS3 - 151 - Even shorter

a=99
o=" of beer"
f=" bottle"
d=" on the wall"
g=f+"s"+o
while(a)e=a^1?g:f+o,trace(a+e+d+", "+a+e+".\nTake one down and pass it around, "+--a+(a^1?g:f+o)+d)
share|improve this answer

C

I must have missed this question, so here's a version I posted as an answer elsewhere. It's a C quine based version. Compile and run to get next line of song. Repeat until bored. If code says "Time to go..." then enter number of beers next time you run as a command line argument.

// Time to go to the shop and get some beer
//
//
//
//
// #####.#####.#####.#####.#####.#####.#####
// ##.#####.#####.#####.#####.#####.#####.##
// #####.#####.#####.#####.#####.#####.#####
// ##.#####.#####.#####.#####.#####.#####.##

char *z [] = {
"void l(char *s,int b){int i;printf(\"// \");for(i=0;i<b;++i)printf(s);",
"printf(\"\\n\");}\nint main(int argc, char *argv[]){\nint i,j,k,x=%d;",
"char*p;\nif(!x&&argc==2)x=atoi(argv[1]);\nif(!x){printf(\"// Time to ",
"go to the shop and get some beer\\n//\\n//\\n//\\n//\\n\");k=7;\n",
"}else{printf(\"// %%d bottles of beer on the wall, %%d bottles of beer",
".\\n\",x,x);printf(\"// Take one down and pass it round, \");\n",
"if(x>1)printf(\"%%d bottles of beer on the wall.\\n//\\n\",x-1);\n",
"else printf(\"no more bottles of beer on the wall.\\n//\\n\");\n",
"k=x>2?x:2;l(\"  ^   \",x);l(\" / \\\\  \",x);l(\"/   \\\\ \",x);",
"l(\"|   | \",x);l(\"|Duf| \",x);l(\"|   | \",x);l(\"----- \",x);}\n",
"for(i=0;i<4;++i){\nprintf(\"// %%s\", i&1 ? \"##.\" : \"\");\n",
"for(j=i&1;j<k;++j)\nprintf(\"%%s#####\",j!=(i&1)?\".\":\"\");\n",
"printf(\"%%s\\n\",i&1?\".##\":\"\");}\nprintf(\"\\nchar *z [] = {\\n\");\n",
"for(i=0;i<sizeof z/sizeof z[0];++i){\nprintf(\"\\\"\");\n",
"for(p=z[i];*p;++p)\nswitch (*p){\ncase '\\n':printf(\"\\\\n\");break;\n",
"case '\\\\':printf(\"%%c%%c\",92,92);break;\n",
"case '%%':printf(\"%%c\",37);break;\ncase '\"':printf(\"%%c%%c\",92,'\"');break;\n",
"default:printf(\"%%c\", *p);break;}\nprintf(\"\\\",\\n\");}\n",
"printf(\"};\\n\");\nfor(i=0;i<sizeof z/sizeof z[0];++i)\n",
"printf(z[i],x?x-1:0);}\n",
};
void l(char *s,int b){int i;printf("// ");for(i=0;i<b;++i)printf(s);printf("\n");}
int main(int argc, char *argv[]){
int i,j,k,x=0;char*p;
if(!x&&argc==2)x=atoi(argv[1]);
if(!x){printf("// Time to go to the shop and get some beer\n//\n//\n//\n//\n");k=7;
}else{printf("// %d bottles of beer on the wall, %d bottles of beer.\n",x,x);printf("// Take one down and pass it round, ");
if(x>1)printf("%d bottles of beer on the wall.\n//\n",x-1);
else printf("no more bottles of beer on the wall.\n//\n");
k=x>2?x:2;l("  ^   ",x);l(" / \\  ",x);l("/   \\ ",x);l("|   | ",x);l("|Duf| ",x);l("|   | ",x);l("----- ",x);}
for(i=0;i<4;++i){
printf("// %s", i&1 ? "##." : "");
for(j=i&1;j<k;++j)
printf("%s#####",j!=(i&1)?".":"");
printf("%s\n",i&1?".##":"");}
printf("\nchar *z [] = {\n");
for(i=0;i<sizeof z/sizeof z[0];++i){
printf("\"");
for(p=z[i];*p;++p)
switch (*p){
case '\n':printf("\\n");break;
case '\\':printf("%c%c",92,92);break;
case '%':printf("%c",37);break;
case '"':printf("%c%c",92,'"');break;
default:printf("%c", *p);break;}
printf("\",\n");}
printf("};\n");
for(i=0;i<sizeof z/sizeof z[0];++i)
printf(z[i],x?x-1:0);}
share|improve this answer

Python

i=99
while i>0:
 k,b,o="%s bottles"," of beer"," on the wall"
 if i==1:k=k[:9]+k[10:]
 '%s, %s.'%(k+b+o,k+b)%(i,i)
 if i!=1:'Take one down and pass it around, %s'%x[:31]%(i-1)
 i-=1
else: 'Go to the store and buy some more, %ss%s.'%(k,o)%99
share|improve this answer
1  
what language is this? – Nate Koppenhaver Oct 15 '11 at 1:27
show 2 more comments
for i in range(99,0,-1): r=", ";m=i-1;n=".\n";v='s';k=(v,'')[m<2];b=" of beer";w=" on the wall";a=" bottle";y=a+v+b;s=`i`+y+w+r+`i`+y+n+"Take one down and pass it around"+r+`m`+a+k+b+w+n;t=`i`+a+b+w+r+`i`+a+b+n+"Go to the store and buy some more, 99"+y+w+n;print (s,t)[i<2]

python one liner

share|improve this answer
1  
How about one line with no semi-colons? I'd +1 that. – primo Mar 14 at 18:27

Python - a lot

Amidoinitrite?

print"""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.

....

  Ok, this is stupid. First of all, what the brainfuck are the bottles doing on the wall? They're not spiders nor picture frames. And how are they sitting on the wall?

94 bottles of beer on the wall, 9.. oops, they fell down. 94 bottles of beer on the floor, 94 bottles of beer.

  Second.. who the HQ9+ wants to keep track? I think I lost count after drinking the 2nd one...

Take one ... um... up, and pass it around,  .....  er.. a lot of bottles of beer still on the floor.

  Fourthly, what's with this passing around scheme? They're not j..I mean letters, yeah, or boxes of chocolate. We all can just take one and drink it. It's healthier too.

A pile of bottles of beer on the floor, a pile of bottles of beer.
Everyone take one up and drink it, still a whole bunch of bottles of beer on the floor.

  Um.. seventhly, are we really that many in this assembly that we can finish 200 or however many bottles we had in the beginning? Without passing out?

Go to the store and buy some more

  Yeah and who's gonna pay for it? Definitely not me. And how are you going to bring 300 bottles back from the store?
  In your car? Buddy, you're so drunk, you can't even C anything. Go home dude, go home. Take a cab."""

Additional reference (helped me a lot with the code): http://www.youtube.com/watch?v=Y0Z0raWIHXk

share|improve this answer

Ruby — 199

Censored version, until we decide, what to do with http://www.codegolf.com questions.

g,x=" on the wall"
puts CENSORED.map{|i|CENSOREDbottle#{CENSORED1} of beerCENSORED

#{xCENSORED}."}.reverse*"
Take one down and pass it around, ")CENSORED,"Go to the store and buy some more,CENSORED"
share|improve this answer
show 2 more comments
1 2 3

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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