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

100
votes
\$\begingroup\$

Brainf*** (1,509)

I figured I could trump this answer by not only making 9 beer bottles instead of 1, but also by only using 7 different characters in the code.

    +++           +++           +++           [>+           +++           ++>           +++           +++           <<- 
    ]>+           ++>           +++           >++           +++           +++           ++>           +++           +++ 
   +++>+         +++++         +++++         [>+++         >++++         >++++         <<<-]         >->>+         +>+++ 
   +++++         [>+++         +++++         ++++>         +++++         +++++         ++>++         +++++         +++++ 
   >++++         +++++         +++>+         +++++         +++++         +>+++         +++++         +++++         >++++
   +++++         ++++>         +++++         +++++         +++>+         +++++         +++++         ++>++         +++++ 
  ++++++>       +++++++       ++++++>       +++++++       +++++++       >++++++       +++++++       +>+++++       +++++++
  ++>++++       +++++++       +++>+++       +++++++       ++++>++       +++++++       +++++<<       <<<<<<<       <<<<<<<
  <-]>+>+       +>++++>       +++++>+       +++++>>       +>+++>+       +++>+++       +++>+++       ++++>>+       +>+++>+ 
 +++>+++++     >+++++++<     <<<<<<<<<     <<<<<<<<<     <<<<[>[<<     <.>.>>>>.     >>>>>.>>>     >>>>>>.>>     >>..<<<<<
<.<<<<<.>>>   >>>>>>>.<<<   <<<<<<<<<<<   <<<.>>>>>>>   >>>>>>>.<<<   <<<.<<<<<<<   <.>>>>>.>>.   .>>>>>>>>>.   <<<<<<<<<<<
<<<<<.>>>>>   >>>>>>>>>.<   .<<<<<<<<<<   <<<.>>>>>>>   >>>>>>>>>>>   .<<<<<<<<<.   <<.<<<<<<<.   >>>>>>>>>>>   >>>>>>>>>.<
<<<<<<<<<<<   <<<<.>>>>>>   >>..<<<<<<<   <<<<.<.<<<<   <.>.>>>>.>>   >>>.>>>>>>>   >>.>>>>..<<   <<<<.<<<<<.   >>>>>>>>>>.
<<<<<<<<<<<   <<<<<<.>>>>   >>>>>>>>>>.   <<<<<<.<<<<   <<<<.>>>>>.   >>..>>>>>>>   >>.<<<<<<<<   <<<<<<<.<.>   >>>>>>>>>>>
>>>>>>.<<<<   <<<<<<<<<<.   >>>>>>>.<<<   <.<<<<<<<.>   >>>>>>>>>>>   >>.<.<<<<<<   .<<<<<<<.>>   >>>>.>>>>>>   >>.>>>>>>.<
<<<<<<.<<<<   <<<<<<<<<.>   >>>.>>>>>>>   >>.<<<<<<<.   <<<<<<.>>>>   >>>>>>>>>>>   .<<<<<<<<<<   <.>>>>>>>>>   >>>>..<<<<<
<<<<<<<<<<<   <.>>>>>>>>>   >.>>>>>>>>.   <<<<<<<<<<<   <<<<<<<.>>>   >.>>>>>>>>>   >>>.<<.>>>>   >.<<<<<<.<<   <<<<<.<<<<<
.<.<<<<<.>-   .>>>>.>>>>>   .>>>>>>>>>.   >>>>..<<<<<   <.<<<<<.>>>   >>>>>>>.<<<   <<<<<<<<<<<   <<<.>>>>>>>   >>>>>>>.<<<
<<<.<<<<<<<   <.>>>>>.>>.   .>>>>>>>>>.   <<<<<<<<<<<   <<<<<.>>>>>   >>>>>>>>>.<   .<<<<<<<<<<   <<<.>>>>>>>   >>>>>>>>>>>
 .<< < <<<     <<< . <<.     <<< < <<<     .>> > >>>     >>> > >>>     >>> > >>>     .<< < <<<     <<< < <<<     <<< . >>> 
  >> >>>.       .<<< <<       <<<< <.       << . <<       -]+ +++       ++ + ++       << + ++       ++ + ++       +<->>-]

I do have to admit though, there is a bug in the code (maybe you can figure out how to fix it for me?) and it does not print the final sentence, Go to the store and buy some more, 99 bottles of beer on the wall. But other than that, it functions just as well as any of the programs made in those sissy programming languages everyone else seems to like to use.

\$\endgroup\$
2
  • 9
    \$\begingroup\$ You only have 9 bottles there. You need 90 more! \$\endgroup\$
    – Joe Z.
    Mar 15, 2013 at 20:32
  • \$\begingroup\$ Petition: rename this language to braindrunk ? \$\endgroup\$
    – Cyoce
    Dec 16, 2015 at 18:55
99
votes
\$\begingroup\$

Funciton

I wrote this just the other day. :) (Screenshots: start and finish)

Since this looks ugly in StackExchange due to the extra line spacing, consider running the following code in your browser’s JavaScript console to fix that: $('pre').css('line-height',1)

                                            ╓┬────╖
     ╔════╗  ┌───╖                          ╟┘99b ║
     ║ −1 ╟──┤ + ╟──┐                       ╙──┬──╜
     ╚════╝  ╘═╤═╝  ├──────────────────────────┴─────────────────────────────┐
     ╔════╗  ┌─┴─╖  │  ╔════════════════════════════════════════════════════╗│
     ║ 99 ╟──┤ ? ╟──┘  ║ 93438979891487426396059469986395555362079573844971 ║│
     ╚════╝  ╘═╤═╝     ║ 71377306928718494179034460561943201885027745835961 ║│
            ┌──┴───╖   ║ 98129935108241412387473531261660077880505710501626 ║│
    ╔════╗  │ 99bp ║   ║ 32694396343717333192558234646820019070451056711    ║│
    ║ 99 ║  ╘══╤═══╝   ╚══════════════════════════╤═════════════════════════╝│
    ╚═╤══╝   ┌─┴─╖                       ┌───╖  ┌─┴─╖  ╔═════════════════╗   │
   ┌──┴──╖   │ ‼ ╟───────────────────────┤ ‼ ╟──┤ ? ╟──╢ 445551776368547 ║   │
   │ 99b ║   ╘═╤═╝┌─────────────────────┐╘═╤═╝  ╘═╤═╝  ║ 925186328623383 ║   │
   ╘══╤══╝     │  │╔═══════════════════╗│  │      │    ║ 851314944882510 ║   │
      │        │  │║ 15177132563375318 ║│  │      │    ║ 812246570019017 ║   │
 ╔════════╗    │  │║ 07655616350359109 ║│  │      │    ║ 240477365113929 ║   │
 ║ 318287 ║    │  │║ 82597577171382437 ║│  │      │    ║ 659548419629671 ║   │
 ║ 023073 ║    │  │║ 18150105146396039 ║│  │      │    ║ 952755268258505 ║   │
 ║ 603558 ║    │  │║ 2022986808360992  ║│  │      │    ║ 759402210908648 ║   │
 ║ 743780 ║    │  │╚══════════╤════════╝│  │      │    ║ 737406010882693 ║   │
 ║ 068900 ║    │  │         ┌─┴─╖ ┌───╖ │  │      │    ║ 018745757193818 ║   │
 ║ 028319 ║    │  │         │ ‼ ╟─┤ ‼ ╟─┘  │      │    ║ 597439618635403 ║   │
 ║ 948400 ║    │  │         ╘═╤═╝ ╘═╤═╝    │      │    ║ 821854707881243 ║   │
 ║ 620075 ║    │  │         ┌─┴─╖   │    ┌─┴─╖    │    ║ 92049082452     ║   │
 ║ 955580 ║    │  └─────┬───┤ ‼ ╟────────┤ ‼ ║    │    ╚═════════════════╝   │
 ║ 347161 ║    │        │   ╘═══╝┌──────┐╘═╤═╝    └─────────────┐            │
 ║ 651333 ║    │   ╔═══╗│┌──────╖│╔════╗│ ╔╧═════════╗          │            │
 ║ 590970 ║    │   ║ 0 ║└┤ 99bp ╟┘║ −1 ║└┐║ 20971566 ║          ├────────────┘
 ║ 678045 ║    │   ╚══╤╝ ╘══════╝ ╚══╤═╝ │╚══════════╝          │
 ║ 336290 ║  ┌─┴─╖  ┌─┴─╖  ┌─────╖  ┌┴──╖├──────────────────────┘
 ║ 721824 ╟──┤ ‼ ╟──┤ ? ╟──┤ 99b ╟──┤ + ║│
 ╚════════╝  ╘═══╝  ╘═╤═╝  ╘═════╝  ╘═╤═╝│    ╓┬──────╖
                      └───────┬───────┘  │    ╟┘ 99bp ║
                              └──────────┘    ╙───┬───╜
 ┌────────────────────────────────────────────────┴──────────────┐
 │╔══════════════════════════════════════════╗╔═══════════╗      │
 │║ 8592134145756414358602136806465202028576 ║║ 232783950 ║      │
 │╚══════════════════════════════╤═══════════╝╚╤══════════╝      │
 │               ┌───╖  ╔═══╗  ┌─┴─╖  ┌───╖  ┌─┴─╖  ┌─────────╖  │
 └───────────────┤ = ╟──╢ 1 ║  │ ‼ ╟──┤ ‼ ╟──┤ ? ╟──┤ int→str ╟──┴┐
                 ╘═╤═╝  ╚═══╝  ╘═╤═╝  ╘═╤═╝  ╘═╤═╝  ╘═════════╝   │
          ╔═══╗  ┌─┴─╖         ┌─┴─╖    │      └──────────────────┘
          ║ 0 ╟──┤ ? ╟─────────┤ ‼ ╟──┐
          ╚═══╝  ╘═╤═╝         ╘═══╝  │
              ╔════╧╗╔════════════════╧════════════════════════════════╗
              ║ 115 ║║ 20338288213193790107412311132593873016630280224 ║
              ╚═════╝╚═════════════════════════════════════════════════╝
\$\endgroup\$
3
  • 1
    \$\begingroup\$ plus one, this is awesome \$\endgroup\$
    – gyurisc
    Jul 28, 2011 at 12:38
  • 1
    \$\begingroup\$ That language is amazing, great job! \$\endgroup\$ Mar 11, 2012 at 11:54
  • 1
    \$\begingroup\$ I saw this on Esolang.org and liked the look of it. \$\endgroup\$
    – M L
    Jul 28, 2015 at 16:13
69
votes
\$\begingroup\$

Perl (410 characters)

There's already a website dedicated to this contest:

One of the Perl solutions would be very very hard to beat in terms of creativity, it reads:

[bottles.pl]


         $a=
        "cpuu
       \bmft p
       \bg cff
       \bs";$b
       ="po ui
       \bf xbm
      \bm";$c="
      Ypv ublf p
     \bof epxo qb
   \btt ju bspvoe";
  $a =~ s/\n//;$a =~
  s/\s+/ /g; $b   =~
  s/\n// ;  $b    =~
  s/\s+/ /g;$c    =~
  s/\n// ;  $c    =~
  s/\s+/ /g;$a    =~
  y/b-z/a-z/;$b   =~
  tr/b-z/a-z/;$c  =~
  tr/b-z/a-z/ ; for(
  $d=100;$d>0;$d--){
  print"$d $a $b $d"
  ;print" $a,\n$c, "
  ;print($d-1);print
  " $a $b.\n";} $x =
  "cjc"; $y="dobbz";
  $z="com";print"\n"
  ;print "- $x\@$y."
   ;print"$z \n\n";

Here's the link to the original file.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice presentation, but this don't match request!! \$\endgroup\$ Feb 7, 2014 at 8:39
  • \$\begingroup\$ A 'rot1' cipher, not the best attempt at obfuscation I've seen. The use of \b to 'remove' unwanted characters is also a bit disappointing. \$\endgroup\$
    – primo
    Jun 14, 2014 at 15:26
56
votes
\$\begingroup\$

jQuery + FireBug Console

$('code:first').text()

;)

\$\endgroup\$
10
  • 2
    \$\begingroup\$ What about something like eval($($('code')[8]).text().replace(/print/g,'console.log')) <del>(aka. stealing)</del>? It prints the whole lyrics of the song. :P \$\endgroup\$
    – JiminP
    Jul 26, 2011 at 8:59
  • 2
    \$\begingroup\$ Also works on Chrome's javascript console. \$\endgroup\$
    – Spoike
    Sep 22, 2011 at 8:08
  • \$\begingroup\$ Devilishly clever. \$\endgroup\$
    – Maxpm
    Feb 28, 2012 at 3:28
  • 1
    \$\begingroup\$ @JiminP Unfortunately, that's not a stable selector given how the answer order can change over time (in fact, it no longer works). \$\endgroup\$
    – Muhd
    Dec 21, 2013 at 0:52
  • 2
    \$\begingroup\$ @Muhd Still works as long as the question isn't changed - the first code block is the one in the question. \$\endgroup\$
    – Bob
    Jan 17, 2014 at 5:15
24
votes
\$\begingroup\$

HQ9+ (1 character)

9

Admittedly its not a Turing complete language, but this still counts

\$\endgroup\$
2
  • 13
    \$\begingroup\$ Why don't you use HQ9 B? It's Turing complete. \$\endgroup\$ Apr 30, 2011 at 5:25
  • 1
    \$\begingroup\$ @muntoo I'm not sure HQ9+B is turing complete.. The command B polls the keyboard input and evaluates that as brainfuck so it's HQ9+ with an optonal Brainfuck interpreter. i.e. the program "B" in HQ9+B will poll stdin until it gets ! (or EOF) and interpret that as Brainfuck.. \$\endgroup\$
    – Sylwester
    Feb 6, 2014 at 21:37
20
votes
\$\begingroup\$

Who said C# had too much ceremony? Whoever it was, they have never been so right.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace _99Bottles
{
    class Program
    {
        static void Main(string[] args)
        {
            PrintSong(99);
        }

        static void PrintSong(int bottleCount)
        {
            Func<int, string> sOrBlank = howMany => howMany > 1 ? "s" : "";

            PrintBottles(howManyBottles =>
            {
                Console.WriteLine("{0} bottle{1} of beer on the wall, {0} bottle{1} of beer.", howManyBottles, sOrBlank(howManyBottles));
                if (howManyBottles > 1)
                {
                    Console.WriteLine("Take one down and pass it around, {0} bottle{1} of beer on the wall.", --howManyBottles, sOrBlank(howManyBottles));
                }
                else
                {
                    Console.WriteLine("Go to the store and buy some more, 99 bottles of beer on the wall.", --howManyBottles);
                }
            },
            bottleCount);
        }

        static void PrintBottles(Action<int> printBottles, int count)
        {
            printBottles(count);

            if (count > 1)
            {
                PrintBottles(printBottles, --count);
            }
         }
    }
}
\$\endgroup\$
5
  • 11
    \$\begingroup\$ +1 For being another C-style sacrificial lamb in an ocean of Perl. \$\endgroup\$ Jan 27, 2011 at 21:26
  • \$\begingroup\$ That can be reduced quite substantially. \$\endgroup\$
    – Nellius
    Jan 28, 2011 at 9:39
  • 2
    \$\begingroup\$ @Nellius Did you even read what ilivewithian said before his code? \$\endgroup\$ Jan 28, 2011 at 14:08
  • 1
    \$\begingroup\$ @Daniel Yes, and it implies that he thinks everything in his code is necessary. If meant as a joke, it shouldn't be voted up this much. It's not short, creative, efficient, or even slightly clever. \$\endgroup\$
    – Nellius
    Jan 28, 2011 at 14:16
  • \$\begingroup\$ @Nellius It wasn't meant as a serious contender, on no level is this good code. I'm sure it can be reduced, made more efficient and generally improved considerably. \$\endgroup\$
    – Rob White
    Jan 28, 2011 at 15:10
18
votes
\$\begingroup\$

C

This program is generating the complete song text as single string using the preprocessor. The actual C code just outputs the string thus constructed. Calling strings on the generated executable will reveal the complete song text in the executable.

#define BOTTLES(n) n " bottles of beer"
#define BOTTLE "1 bottle of beer"
#define OTW " on the wall, "
#define TAKE "Take one down, pass it around, "
#define BUY "Go to the store and buy some more, "
#define STOP "."
#define NL "\n"

#define LINE1(n) BOTTLES(n) OTW BOTTLES(n) STOP NL
#define LINE1A BOTTLE OTW BOTTLE STOP NL
#define LINE2(n) TAKE BOTTLES(n) STOP NL
#define LINE2A TAKE BOTTLE STOP NL
#define LINEX BUY BOTTLES("99") NL

#define MIDDLEPART(n) LINE2(n) NL LINE1(n)
#define MIDDLELAST LINE2A NL LINE1A

#define EIGHT_TO_TWO(S, M) M(S "8") M(S "7") M(S "6") M(S "5") M(S "4") M(S "3") M(S "2")
#define EIGHT_TO_ONE(S, M) EIGHT_TO_TWO(S, M) M(S "1")
#define EIGHT_TO_TWO_AGAIN(S, M) M(S "8") M(S "7") M(S "6") M(S "5") M(S "4") M(S "3") M(S "2")
#define EIGHT_TO_ONE_AGAIN(S, M) EIGHT_TO_TWO_AGAIN(S, M) M(S "1")
#define NINE_TO_TWO(S, M) M(S "9") EIGHT_TO_TWO(S, M)
#define EIGHT_TO_ZERO(S, M) EIGHT_TO_ONE(S, M) M(S "0")
#define NINE_TO_ZERO(S, M) M(S "9") EIGHT_TO_ZERO(S, M)

#define NINETIES EIGHT_TO_ZERO("9", MIDDLEPART)
#define NTIES(n) NINE_TO_ZERO(n, MIDDLEPART)
#define EIGHTIES_TO_TENS EIGHT_TO_ONE_AGAIN("", NTIES)
#define NAUGHTIES NINE_TO_TWO("", MIDDLEPART)

#define SONG LINE1("99") NINETIES EIGHTIES_TO_TENS NAUGHTIES MIDDLELAST LINEX

#include <stdio.h>

int main()
{
  puts(SONG);
  return 0;
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Probably the most efficient and fastest solutions of these. \$\endgroup\$ Jun 6, 2014 at 13:20
  • 1
    \$\begingroup\$ @tomp Efficient timewise, very inefficient in the executable file size :) \$\endgroup\$
    – seequ
    Oct 7, 2014 at 5:03
14
votes
\$\begingroup\$

C# (312 310 304 characters)

class P{static void Main(){string b=" bottle",w=" on the wall",o=" of beer",p=".\n",s="s";for(int i=99;i>0;i--)System.Console.Write(i+b+(i>1?s:"")+o+w+", "+i+b+(i>1?s:"")+o+p+(i>1?"Take one down and pass it around, "+(i-1)+b+(i-1>1?s:"")+o+w+p+"\n":"Go to the store and buy some more, "+99+b+s+o+w+p));}}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I can't believe you got it in shorter than me. I'm impressed. I'll have to study for a better set of options \$\endgroup\$
    – jcolebrand
    Jan 29, 2011 at 6:30
  • \$\begingroup\$ And now I have studied for it, I'm down to under 300 ;) \$\endgroup\$
    – jcolebrand
    Jan 29, 2011 at 6:38
12
votes
\$\begingroup\$

C#

Not intended to be short, but perhaps this counts as creative?

using System;
using System.Linq;

class Program
{
    static void Main()
    {
        Console.WriteLine(string.Join(Environment.NewLine, Enumerable.Range(0, 100).Select(i =>
            string.Format(
                string.Format(
                    "{0} {1} {{3}} {{4}},{{9}}{0} {1} {{3}}.{{9}}{2},{{9}}{3} {4} {{3}} {{4}}.{{9}}",
                    i == 99 ? "{0}" : "{7}",
                    i == 98 ? "{1}" : "{2}",
                    i == 99 ? "{6}" : "{5}",
                    i == 98 ? "{0}" : "{8}",
                    i == 97 ? "{1}" : "{2}"
                ),
                "No",
                "bottle",
                "bottles",
                "of beer",
                "on the wall",
                "Take one down, pass it around",
                "Go to the store, buy some more",
                99 - i,
                (198 - i) % 100,
                Environment.NewLine
        ))));
    }
}

Note this is just a single statement :)

\$\endgroup\$
11
votes
\$\begingroup\$

Definitely doesn't qualify as creative, but it gets'r done from the command line with a single command.

perl -e '$i=99;while($i>1){print("$i bottles of beer on the wall, $i bottles of beer.\nTake one down and pass it around, ".--$i." bottles of beer on the wall\n\n");}print("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.\n");'
\$\endgroup\$
0
11
votes
\$\begingroup\$

Haskell, 272, 250, 243 characters

(&)=(++)
b 1=" bottle"
b _=b 1&"s"
w=" on the wall"
p n=show n&b n&" of beer"
f n=putStrLn$p n&w&","&p n&".\n"&c(n-1)
c 0="Go to the store and buy some more, "&p 99&w&"."
c n="Take one down and pass it around, "&p n&w&"\n"
main=mapM f[99,98..1]
\$\endgroup\$
11
votes
\$\begingroup\$

Windows PowerShell (198)

filter b{"$_ bottle$('s'*!!--$_) of beer"}(99..1|%{($_|b)+($w=' on the wall')+", $($_|b)."
"Take one down and pass it around, $(--$_|b)$w.
"})[0..196]
"Go to the store and buy some more, $(99|b)$w."

Fairly straightforward.

I'm using a filter for the bottles of beer, since function is longer and invocation needs parentheses in any case. The plural detection (!!--$_) first decrements the number of bottles by one (so plural is anything non-zero), casts it to boolean and negates it with the first ! and negates it again so we now have a boolean describing whether the number needs a plural or not. This is then implicitly casted to an integer when multiplying the string.

Inline line breaks are fun.

Spawning more lines than needed and cutting back afterwards, too.

\$\endgroup\$
4
  • \$\begingroup\$ Definitely short, and this set a bar to try and go under!!! Though from my point of view, the appearance of a "magic number" like 196 was in the class of things I hope to be able to avoid because it captures (99 * 2) - 2. For an answer where you can change the bottle count in one place :) see codegolf.stackexchange.com/questions/2/99-bottles-of-beer/… \$\endgroup\$ Feb 3, 2011 at 18:32
  • \$\begingroup\$ You're missing "on the wall." in the final line of output and after every bottle is taken down. \$\endgroup\$
    – Iszi
    Nov 24, 2013 at 2:52
  • \$\begingroup\$ filter b{"$_ bottle$('s'*!!--$_) of beer"}(99..1|%{($_|b)+($w=' on the wall')+", $($_|b).";"Take one down and pass it around, $(--$_|b)$w. "})[0..196];"Go to the store and buy some more, $(99|b) $w." fixes that. Totals 199 characters. (Add a line break after $w before ") \$\endgroup\$
    – Iszi
    Nov 24, 2013 at 3:19
  • \$\begingroup\$ Thanks for the fix. There was a superfluous space in there too, so the count is 198 instead. \$\endgroup\$
    – Joey
    Nov 24, 2013 at 12:07
10
votes
\$\begingroup\$

Curl 19 characters

(requires internet connection)

curl -L j.mp/eGv9K5
\$\endgroup\$
4
  • 7
    \$\begingroup\$ I consider this stretching it too far. \$\endgroup\$
    – moinudin
    Jan 28, 2011 at 11:24
  • 8
    \$\begingroup\$ I consider it a joke. Many solutions can be hidden behind a query to a web server. \$\endgroup\$
    – Alexandru
    Jan 28, 2011 at 15:48
  • 3
    \$\begingroup\$ I like this one nevertheless. \$\endgroup\$
    – pimvdb
    May 31, 2011 at 19:53
  • 1
    \$\begingroup\$ If objective was shortest code, I'd give you a point for cleverness. \$\endgroup\$
    – Neil
    Jul 7, 2011 at 14:15
9
votes
\$\begingroup\$

Almost-correct anti-golf from the uber-eager new C programmer who's learning Perl?

#!/usr/bin/perl
#      ^
#      |
#      |
# That's the Perl interpreter.
# You might need to change this line based on
# your Linux/Unix distribution.

# Pragmas for debugging!
use strict;
use warnings;

# Library dependencies...none! lolz

# Main implementation
my $number_of_bottles_of_beer_on_the_wall = 99; #start with 99 bottles
LOOP: while( $number_of_bottles_of_beer_on_the_wall > 0 )
{
  printf( "%d bottles of beer on the wall, %d bottles of beer\n",
          $number_of_bottles_of_beer_on_the_wall,
          $number_of_bottles_of_beer_on_the_wall,                  );

  if( $number_of_bottles_of_beer_on_the_wall > 1 )
  {
    $number_of_bottles_of_beer_on_the_wall -= 1;
    printf( "Take one down and pass it around, %d bottles of beer on the wall.\n\n",
            $number_of_bottles_of_beer_on_the_wall,                               );
  }
  else
  {
    printf( "Go to the store and buy some more, %d bottles of beer on the wall\n",
            99                                                                     );
    last LOOP;
  }
}
\$\endgroup\$
2
  • \$\begingroup\$ Why not /usr/bin/env perl? \$\endgroup\$
    – Luna
    Dec 28, 2014 at 8:41
  • 1
    \$\begingroup\$ @nyuszika7h Insightful critique! ;) \$\endgroup\$ Dec 30, 2014 at 0:36
8
votes
\$\begingroup\$

JavaScript (216 228 215)

for(a=99,c=" on the wall";a;)document.write((d=eval(b="(a||99)+' bottle'+(a-1?'s':'')+' of beer'"))+c+", "+d+".<br>"+(--a?"Take one down and pass it around, ":"Go to the store and buy some more, ")+eval(b)+c+".<p>")

Edit: Had a single "1 bottles of beer" in initial version, 3rd version is completely rewritten, notice cool tricks like (a||99) to get 99 in the last line, (a-1?'s':'') making plural for every case but a==1 though without need for the wasteful ==, and setting the value of b inside a statement where it is used.

\$\endgroup\$
5
  • \$\begingroup\$ It looks like your bottle/bottles optimization is costing you more characters than it saves. \$\endgroup\$
    – Yahel
    Jan 28, 2011 at 13:26
  • \$\begingroup\$ I'm not sure what you mean, what exactly would you change? \$\endgroup\$ Jan 29, 2011 at 0:22
  • \$\begingroup\$ This one stops one verse too early. Last verse should go "no more bottles of beer on the wall, no more bottles..." -- See: 99-bottles-of-beer.net/lyrics.html \$\endgroup\$ Oct 7, 2014 at 0:41
  • \$\begingroup\$ BTW, I managed a full, correct version in 233 bytes: for(o,e,n=100,t=" on the wall";n-->-1;)o=e+t+", "+e+".<br>"+(n>-1?"Take one down, pass it around, ":"Go to the store and buy some more, ")+(e=(0>n?99:n||"no more")+" bottle"+(1!=n?"s":"")+" of beer")+t+".<p>",99>n&&document.write(o) \$\endgroup\$ Oct 7, 2014 at 0:42
  • \$\begingroup\$ @MárÖrlygsson Welcome to the site. The lyrics for this challenge are defined in the opening post. \$\endgroup\$ Oct 7, 2014 at 11:08
7
votes
\$\begingroup\$

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);}
\$\endgroup\$
1
  • \$\begingroup\$ @DreamWarrior in regards to your proposed edit, have you considered putting your code in pastebin so that you could post it as a comment? \$\endgroup\$
    – nderscore
    May 29, 2014 at 21:03
6
votes
\$\begingroup\$

Javascript (285)

This assumes there is a function called print, to output a string.

b=' of beer on the wall';n=100;while(--n>1)if(n>1)print(n+" bottles"+b+', '+n+" bottles of beer.\nTake one down and pass it around, "+(n-1)+' bottle'+(n-1>1?'s':'')+b+'.\n\n');print("1 bottle"+b+", 1 bottle of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.")
\$\endgroup\$
10
  • 8
    \$\begingroup\$ I'm not sure that assumed functions are fair. For example, my program could be b();. Assuming there is a function b() that prints 99 bottles of beer on the wall. :) \$\endgroup\$ Jan 27, 2011 at 21:37
  • 10
    \$\begingroup\$ Javascript doesn't provide any standard way to output a string, if you are running it in a browser, it doesn't have a print function, if you are running it in rhino, you do. \$\endgroup\$
    – user11
    Jan 27, 2011 at 21:39
  • 2
    \$\begingroup\$ document.writeln works. \$\endgroup\$ Jan 27, 2011 at 21:44
  • 4
    \$\begingroup\$ ... for browsers \$\endgroup\$
    – user11
    Jan 27, 2011 at 21:50
  • 5
    \$\begingroup\$ JavaScript has IO with: alert as output, prompt as variable input and confirm as boolean input. They suck as far as UI goes, but they are the standard blocking IO functions. alert and print are the same length, so your code should be about equal. \$\endgroup\$
    – zzzzBov
    May 14, 2011 at 20:09
6
votes
\$\begingroup\$

Scheme (270)

No whitespace:

(let l((i 99))(let((b" bottle")(c" on the wall")(d"Take one down and pass it around,")(e".\n")(f", ")(g" of beer"))(if(= i 1)(map display`(1,b,g,c,f,1,b,g,e"Go to the store and buy some more, 99",b,c,e))(begin(map display`(,i,b,g,c,f,i,b,e,d,i,b,c,e"\n"))(l(-1+ i))))))

With whitespace:

    (let l ((i 99))
      (let ((b" bottle")
            (c" on the wall")
            (d"Take one down and pass it around, ")
            (e".\n")
            (f", ")
            (g" of beer"))
        (if (= i 1)
            (map display`(1 ,b ,g ,c ,f ,1 ,b ,g ,e
                          "Go to the store and buy some more, 99" ,b ,c ,e))
            (begin (map display `(,i ,b ,g ,c ,f ,i ,b ,e ,d ,i ,b ,c ,e "\n"))
                   (l (-1+ i))))))
\$\endgroup\$
0
6
votes
\$\begingroup\$

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

\$\endgroup\$
5
votes
\$\begingroup\$

Python (318)

I found this way of making a Python program shorter :)

exec'eJxtjrFqwzAQQHd/xVVgLCVqSbq5RHO2TtlcgyX7Qk3luyAphP59ZA0thGzi9O7es0bUERyn5DE/+AwOMdTxi0TljLeLmyzQB4GlaaCBg/hkWDigqMb/76aZz0CHHaCPCLaWTpLSTWw2kl7MXmkBTJC+EW7Wey3U9hmzzqU42R/MNMLEt6KFi40R5gQ28JUmndO0ODIkLhdjyjWFc9dfiLxg6Vsx1ZExu36Vddn2miVD2w59R4d9/6d+f8h7Wze3Y+GrS5gpwSjbVlV3Y1BZCg=='.decode('base64').decode('zip')
\$\endgroup\$
2
  • \$\begingroup\$ this .decode.decode stuff seemed stupid to me the first time i saw it, but i'm now using for practical purposes (to plop python code into my .bashrc as functions in an unobtrusive way), so thanks. \$\endgroup\$
    – ixtmixilix
    Sep 6, 2012 at 22:50
  • 5
    \$\begingroup\$ I count that the uncompressed code has 300 chars. Why compress it then? \$\endgroup\$ May 6, 2013 at 11:47
5
votes
\$\begingroup\$

Rebmu — 167 characters

M N 99 Bdz[cb[n{ bottle}egN 1{s}{}{ of beer}]]loN[cb[b W{ on the wall}C{, }b P{.}lfEZ--n[Nm{Go to the store and buy some more}]{Take one down and pass it around}cBwPlf]]

Could probably shave a few characters off, this was just a first try. :)

Here's equivalent Rebol which has the shorthand boiled out. Still pretty competitive especially considering the clarity:

m: n: 99

b: does [
    combine [n { bottle} either n > 1 {s} {} { of beer}]
]

loop n [
    print combine [
        b w: { on the wall} c: {, } b p: {.} newline

        either 0 == -- n [
            n: m
            {Go to the store and buy some more}
        ] [
            {Take one down, and pass it around}
        ]

        c b w p newline
    ]
]

Commented source code available on GitHub

\$\endgroup\$
5
votes
\$\begingroup\$

PHP: 285 240 233 231 Characters

$i=99;$b=" bottles of beer";$o=" bottle of beer";$c=" on the wall";while($i>1){echo"$i$b$c, $i$b.\nTake one down and pass it around, ".--$i.(($i>1)?$b:$o).$c.".\n\n";}echo"$i$o$c, $i$o.\nGo to the store and buy some more, 99$b$c.";

Output here: http://ideone.com/5fQmcd

\$\endgroup\$
4
votes
\$\begingroup\$

Python, 241 chars

s=""
i=99
b="%d bottl%s of beer"
w=" on the wall"
t="Take one down and pass it around, "
p=q="es"
while i:s+=b%(i,p)+w+", "+b%(i,p)+".\n";i-=1;p=p[:i];s+=t+b%(i,p)+w+".\n\n"
print s[:-64]+"Go to the store and buy some more, "+b%(99,q)+w+"."
\$\endgroup\$
4
votes
\$\begingroup\$

Ruby, 274 bytes

Still pretty new to Ruby, really just playing around

o =" bottles of beer";w=" on the wall";t="Take one down and pass it around, ";s=" bottle of beer"
99.downto(3){|b|puts"#{b}#{o+w}, #{b}#{o}.\n#{t}#{b-1}#{o+w}.\n\n"}
puts"2 #{o+w}, 2 #{o}.\n#{t}1#{s}#{w}.\n\n1#{s+w}, 1#{s}.\nGo to the store and buy some more, 99#{o+w}."
\$\endgroup\$
4
votes
\$\begingroup\$

C# (299 characters)

using System;class D{static void Main(){string a="s",z="",w=" on the wall",q=", ",p=".\n",b=" bottle",c=" of beer";for(int O=99;O>=1;)Console.WriteLine(O+b+(O>1?a:z)+c+w+q+O+b+(O>1?a:z)+c+p+(--O>0?"Take one down and pass it around, "+O:"Go to the store and buy some more, 99")+b+(O==1?z:a)+c+w+p);}}
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Your final line displays "99 bottle" instead of "99 bottles", and you have your loop starting from 19 instead of 99 (though that's probably just an oversight). \$\endgroup\$
    – Nellius
    Jan 28, 2011 at 10:22
  • \$\begingroup\$ @Nellius ~ Corrected ~ and thanks to your competitive code I revisited mine and removed some single insert blocks and reduced some preexisting constants in my own code. Now down to under 300 smoothly. \$\endgroup\$
    – jcolebrand
    Jan 29, 2011 at 6:37
  • \$\begingroup\$ You can get it down to 293 by dropping "using System;" and changing "Console.WriteLine" to "System.Console.WriteLine" \$\endgroup\$
    – Tester101
    May 13, 2011 at 12:26
  • \$\begingroup\$ @Tester101 ~ Good call. Hadn't considered that! \$\endgroup\$
    – jcolebrand
    May 13, 2011 at 14:17
4
votes
\$\begingroup\$

JavaScript (7 functions)

Not golfed. This is intended as a (mostly) functional implementation of the song.

function firstUpper(s) {
    return s.slice(0, 1).toUpperCase() + s.slice(1);
}

function bottles(x) {
    return (x || "no more") + " " + (x == 1 ? "bottle" : "bottles") + " of beer";
}

function wall(x) {
    return bottles(x) + " on the wall";
}

function line1(x) {
    return wall(x) + ", " + bottles(x) + ".";
}

function line2(x, max) {
     return (x ? "take one down and pass it around, " + wall(x - 1) : "go to the store and buy some more, " + wall(max)) + ".";
}

function verse(x, max) {
    return [line1(x), line2(x, max)].map(firstUpper).join("\n") + "\n\n";
}


function song(max) {
    var text = "";
    for(var x = max; x >= 0; x--) {
        text += verse(x, max);
    }
    return text;
}

print(song(99));
\$\endgroup\$
4
votes
\$\begingroup\$

Go (263)

package main
import "fmt"
func main(){b,i,e,r:=fmt.Println,99,"bottles","of beer on the wall"
for i>0{b(i,e,r+",",i,e,r[:7]+".")
if i--;i<2{e=e[:6]}
if i>0{b("Take one down and pass it around,",i,e,r+`.
`)}}
b("Go to the store and buy some more,",99,e+"s",r+".")}
\$\endgroup\$
3
votes
\$\begingroup\$

PHP - 252 bytes

$a=" bottles of beer";$b=str_replace("s","",$a);$c=" on the wall";for($i=98;$i;)echo($j=$i+1).$a.$c.", ".$j.$a.".
Take one down and pass it around, ".$i.($i-->1?$a:$b).$c.".

";echo"1".$b.$c.", 1".$b.".
Go to the store and buy some more, 99".$a.$c.".";

I hope I'll compress some more tomorrow.

\$\endgroup\$
3
votes
\$\begingroup\$

Ruby 1.9.2p136 : 223

I'm no coward, you can read mine ;p

b="%d bottle%s of beer"
w=' on the wall'
99.downto(1){|z|s=b%[z,z>1?'s':'']
puts s+w+", "+s+".
"+(z>1?"Take one down and pass it around, "+b%[z-1,z>2?'s':'']+w+".

" :'Go to the store and buy some more, '+b%[99,'s']+w+".")}
\$\endgroup\$
3
votes
\$\begingroup\$

(Oracle) SQL

No character count, I didn't golf it. Just found this a fun way to do it.

WITH
   bottles AS (
      SELECT LEVEL - 1 AS bottle 
      FROM dual
      CONNECT BY LEVEL <= &number_of_bottles + 1
   ),
   fragments AS (
      SELECT
         'no more ' AS none,
         'bottles of beer' AS supply,
         ' on the wall' AS wall,
         'Take one down and pass it around' AS drink,
         'Go to the store and buy some more' AS refill,
         CHR(13) || CHR(10) AS newline
      FROM dual
   ),
   combined AS (
      SELECT
         b.bottle,
         DECODE(
            b.bottle, 
            1, b.bottle || ' ' || REPLACE(f.supply, 's'),
            0, f.none || f.supply,  
            b.bottle || ' ' || f.supply
         ) AS supply
      FROM bottles b
      CROSS JOIN fragments f

   ),
   two_lines AS (
      SELECT LEVEL AS line
      FROM dual
      CONNECT BY LEVEL <= 2
   )
SELECT
   CASE l.line
      WHEN 1 THEN REPLACE(c1.supply, 'n', 'N') || f.wall || ', ' || c1.supply || '.'
      WHEN 2 THEN DECODE(b.bottle, 0, f.refill, f.drink) || ', '  || c2.supply || f.wall || '.' 
   END AS song 
FROM bottles b
LEFT JOIN combined c1 ON (c1.bottle = b.bottle)
LEFT JOIN combined c2 ON (c2.bottle = DECODE(b.bottle - 1, -1, &number_of_bottles, b.bottle - 1))
CROSS JOIN two_lines l
CROSS JOIN fragments f
ORDER BY
   b.bottle DESC,
   l.line;
\$\endgroup\$
0

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