99 Bottles of Beer

From Rosetta Code
Jump to: navigation, search
Task
99 Bottles of Beer
You are encouraged to solve this task according to the task description, using any language you may know.
The beersong

In this puzzle, write code to print out the entire "99 bottles of beer on the wall" song.

For those who do not know the song, the lyrics follow this form:

X bottles of beer on the wall
X bottles of beer
Take one down, pass it around
X-1 bottles of beer on the wall

X-1 bottles of beer on the wall
...
Take one down, pass it around
0 bottles of beer on the wall

Where X and X-1 are replaced by numbers of course. Grammatical support for "1 bottle of beer" is optional. As with any puzzle, try to do it in as creative/concise/comical a way as possible (simple, obvious solutions allowed, too).

See also

Contents

[edit] 0815

See 99 Bottles of Beer/EsoLang

[edit] 6502 Assembly

See 99 Bottles of Beer/Assembly

[edit] 6800 Assembly

See 99 Bottles of Beer/Assembly


[edit] ABAP

REPORT z99bottles.
 
DATA lv_no_bottles(2) TYPE n VALUE 99.
 
DO lv_no_bottles TIMES.
WRITE lv_no_bottles NO-ZERO.
WRITE ' bottles of beer on the wall'.
NEW-LINE.
WRITE lv_no_bottles NO-ZERO.
WRITE ' bottles of beer'.
NEW-LINE.
WRITE 'Take one down, pass it around'.
NEW-LINE.
SUBTRACT 1 FROM lv_no_bottles.
WRITE lv_no_bottles NO-ZERO.
WRITE ' bottles of beer on the wall'.
WRITE /.
ENDDO.

[edit] ACL2

See 99 Bottles of Beer/Lisp

[edit] ActionScript

for(var numBottles:uint = 99; numBottles > 0; numBottles--)
{
trace(numBottles, " bottles of beer on the wall");
trace(numBottles, " bottles of beer");
trace("Take one down, pass it around");
trace(numBottles - 1, " bottles of beer on the wall\n");
}

[edit] Ada

[edit] Simple version

with Ada.Text_Io; use Ada.Text_Io;
 
procedure Bottles is
begin
for X in reverse 1..99 loop
Put_Line(Integer'Image(X) & " bottles of beer on the wall");
Put_Line(Integer'Image(X) & " bottles of beer");
Put_Line("Take one down, pass it around");
Put_Line(Integer'Image(X - 1) & " bottles of beer on the wall");
New_Line;
end loop;
end Bottles;

[edit] Concurrent version

with 1 task to print out the information and 99 tasks to specify the number of bottles

with Ada.Text_Io; use Ada.Text_Io;
 
procedure Tasking_99_Bottles is
subtype Num_Bottles is Natural range 1..99;
task Print is
entry Set (Num_Bottles);
end Print;
task body Print is
Num : Natural;
begin
for I in reverse Num_Bottles'range loop
select
accept
Set(I) do -- Rendezvous with Counter task I
Num := I;
end Set;
Put_Line(Integer'Image(Num) & " bottles of beer on the wall");
Put_Line(Integer'Image(Num) & " bottles of beer");
Put_Line("Take one down, pass it around");
Put_Line(Integer'Image(Num - 1) & " bottles of beer on the wall");
New_Line;
or terminate; -- end when all Counter tasks have completed
end select;
end loop;
end Print;
task type Counter(I : Num_Bottles);
task body Counter is
begin
Print.Set(I);
end Counter;
type Task_Access is access Counter;
 
Task_List : array(Num_Bottles) of Task_Access;
 
begin
for I in Task_List'range loop -- Create 99 Counter tasks
Task_List(I) := new Counter(I);
end loop;
end Tasking_99_Bottles;

[edit] Aime

integer
main(void)
{
cardinal bottles;
 
bottles = 99;
 
do {
o_cardinal(bottles);
o_text(" bottles of beer on the wall\n");
o_cardinal(bottles);
o_text(" bottles of beer\n");
o_text("Take one down, pass it around\n");
bottles -= 1;
o_cardinal(bottles);
o_text(" bottles of beer on the wall\n\n");
} while (bottles);
 
return 0;
}

[edit] ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
main:(
FOR bottles FROM 99 TO 1 BY -1 DO
printf(($z-d" bottles of beer on the wall"l$, bottles));
printf(($z-d" bottles of beer"l$, bottles));
printf(($"Take one down, pass it around"l$));
printf(($z-d" bottles of beer on the wall"ll$, bottles-1))
OD
)

[edit] AmigaE

PROC main()
DEF t: PTR TO CHAR,
s: PTR TO CHAR,
u: PTR TO CHAR, i, x
t := 'Take one down, pass it around\n'
s := '\d bottle\s of beer\s\n'
u := ' on the wall'
FOR i := 99 TO 0 STEP -1
ForAll({x}, [u, NIL], `WriteF(s, i, IF i <> 1 THEN 's' ELSE NIL,
x))
IF i > 0 THEN WriteF(t)
ENDFOR
ENDPROC

[edit] Apache Ant

Implementation in Apache Ant, due to the limitations of Ant, this requires ant-contrib for arithmetic operations and a dummy target to keep Ant from detecting the loop.

<?xml version="1.0"?>
<project name="n bottles" default="99_bottles">
 
<!-- ant-contrib.sourceforge.net for arithmetic and if -->
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
 
<!-- start count of bottles, you can set this with
e.g. ant -f 99.xml -Dcount=10 -->
<property name="count" value="99"/>
 
<target name="99_bottles">
<antcall target="bottle">
<param name="number" value="${count}"/>
</antcall>
</target>
 
<target name="bottle">
<echo message="${number} bottles of beer on the wall"/>
<echo message="${number} bottles of beer"/>
<echo message="Take one down, pass it around"/>
 
<math result="result" operand1="${number}" operation="-" operand2="1" datatype="int"/>
 
<echo message="${result} bottles of beer on the wall"/>
 
<if>
<not><equals arg1="${result}" arg2="0" /></not>
<then>
<antcall target="bottleiterate">
<param name="number" value="${result}"/>
</antcall>
</then>
</if>
</target>
 
<target name="bottleiterate">
<antcall target="bottle">
<param name="number" value="${number}"/>
</antcall>
</target>
 
</project>

[edit] APL

Works with: Dyalog APL
Translation of: J
     bob  ←  { (⍕⍵), ' bottle', (1=⍵)↓'s of beer'}
     bobw ←  {(bob ⍵) , ' on the wall'}
     beer ←  { (bobw ⍵) , ', ', (bob ⍵) , '; take one down and pass it around, ', bobw ⍵-1}
     ↑beer¨ ⌽(1-⎕IO)+⍳99

[edit] App Inventor

[edit] Using a 'for each <number>' block (simplest)

Note that the output label text is not displayed until the entire lyrics text has been built and there is some delay between button press and display. <CLICK HERE TO VIEW THE BLOCKS AND OUTPUT>

[edit] Using a Clock Timer block (preferrred)

Output can be sent directly to a label with this preferred method as there is no noticeable delay between button press and output. <CLICK HERE TO VIEW THE BLOCKS AND OUTPUT>

[edit] AppleScript

repeat with beerCount from 99 to 1 by -1
set bottles to "bottles"
if beerCount < 99 then
if beerCount = 1 then
set bottles to "bottle"
end
log "" & beerCount & " " & bottles & " of beer on the wall"
log ""
end
log "" & beerCount & " " & bottles & " of beer on the wall"
log "" & beerCount & " " & bottles & " of beer"
log "Take one down, pass it around"
end
log "No more bottles of beer on the wall!"

[edit] Arbre

 
bottle(x):
template: '
$x bottles of beer on the wall.
$x bottles of beer.
Take one down and pass it around,
$y bottles of beer on the wall.
'
 
if x==0
template~{x: 'No more', y: 'No more'}
else
if x==1
template~{x: x, y: 'No more'}
else
template~{x: x, y: x-1}
 
bottles(n):
for x in [n..0]
bottle(x)
 
99bottles():
bottles(99) -> io
 
 


[edit] Argile

use std
 
let X be an int
for each X from 99 down to 1
prints X bottles of beer on the wall
prints X bottles of beer
prints "Take one down, pass it" around
if X == 1
echo No more "beer." Call da "amber lamps"
break
X--
prints X bottles of beer on the wall "\n"
X++
.:around :. -> text {X>59 ? "around", "to me"}
.:bottles:. -> text {X> 5 ? "bottles", (X>1 ? "buttles", "wall")}
.:of beer:. -> text {X>11 ? "of beer", "ov beeer"}
.:on the wall:. -> text {
X>17 ? "on the wall", (X>1 ? "on the bwall", "in the buttle")
}

[edit] ATS

//
#include
"share/atspre_staload.hats"
//
(* ****** ****** *)
 
fun bottles
(n0: int): void = let
//
fun loop (n: int): void =
(
if n > 0 then
(
if n0 > n then println! ();
println! (n, " bottles of beer on the wall");
println! (n, " bottles of beer");
println! ("Take one down, pass it around");
println! (n-1, " bottles of beer on the wall");
loop (n - 1)
) (* end of [if] *)
)
//
in
loop (n0)
end // end of [bottles]
 
(* ****** ****** *)
 
implement main0 () = bottles (99)

[edit] AutoHotkey

See 99 Bottles of Beer/Shell

[edit] AutoIt

See 99 Bottles of Beer/Shell

[edit] AWK

[edit] Regular version

If you don't want so many beers, here you can specify the starting amount.
For example, just a sixpack:

# usage:  gawk  -v i=6  -f beersong.awk
 
function bb(n) {
b = " bottles of beer"
if( n==1 ) { sub("s","",b) }
if( n==0 ) { n="No more" }
return n b
}
 
BEGIN {
if( !i ) { i = 99 }
ow = "on the wall"
td = "Take one down, pass it around."
print "The beersong:\n"
while (i > 0) {
printf( "%s %s,\n%s.\n%s\n%s %s.\n\n",
bb(i), ow, bb(i), td, bb(--i), ow )
if( i==1 ) sub( "one","it", td )
}
print "Go to the store and buy some more!"
}
Output:
The beersong:

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

...

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

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

1 bottle of beer on the wall,
1 bottle of beer.
Take it down, pass it around.
No more bottles of beer on the wall.

Go to the store and buy some more!

[edit] Bottled version

See 99-bottles-of-beer.net

[edit] Babel

main: { 99 bottles }
 
bottles!:
{ x set
{ bw
bx cr <<
"Take one down, pass it around\n" <<
1 x -=
bw "\n" << }
x times }
 
b  : " bottles of beer"
bx!: { x %d << b }
w  : " on the wall"
bw!: { bx w . cr << }
 
x: [0]

[edit] BASIC

See 99 Bottles of Beer/Basic

[edit] FBSL

See 99 Bottles of Beer/Basic

[edit] Integer BASIC

See 99 Bottles of Beer/Basic

[edit] Liberty BASIC

See 99 Bottles of Beer/Basic

[edit] OxygenBasic

See 99 Bottles of Beer/Basic

[edit] PureBasic

See 99 Bottles of Beer/Basic

[edit] REALbasic

See 99 Bottles of Beer/Basic

[edit] Run BASIC

See 99 Bottles of Beer/Basic

[edit] TI-83 BASIC

See 99 Bottles of Beer/Basic

[edit] TI-89 BASIC

See 99 Bottles of Beer/Basic

[edit] Visual Basic

See 99 Bottles of Beer/Basic

[edit] Batch File

See 99 Bottles of Beer/Shell

[edit] Battlestar

 
const bottle = " bottle"
const plural = "s"
const ofbeer = " of beer"
const wall = " on the wall"
const sep = ", "
const takedown = "Take one down and pass it around, "
const u_no = "No"
const l_no = "no"
const more = " more bottles of beer"
const store = "Go to the store and buy some more, "
const dotnl = ".\n"
const nl = "\n"
 
// Print two digits, use the value in a
fun printnum
b = a
loop
break (a < 10)
a /= 10
// modulo is in the d register after idiv
b = d
a += 48 // ASCII value for '0'
print(chr(a))
break
end
a = b
a += 48 // ASCII value for '0'
print(chr(a))
end
 
fun main
loop 99
// Save loop counter for later, twice
c -> stack
c -> stack
 
// Print the loop counter (passed in the a register)
a = c
printnum()
 
// N, "bottles of beer on the wall, "
print(bottle)
print(plural)
print(ofbeer)
print(wall)
print(sep)
 
// Retrieve and print the number
stack -> a
printnum()
 
// N, "bottles of beer."
print(bottle)
print(plural)
print(ofbeer)
print(dotnl)
 
// "Take one down and pass it around,"
print(takedown)
 
// N-1, "bottles of beer on the wall."
stack -> a
a--
// Store N-1, used just a few lines down
a -> stack
printnum()
print(bottle)
// Retrieve N-1
stack -> a
// Write an "s" if the count is not 1
a != 1
print(plural)
end
// Write the rest
print(ofbeer)
print(wall)
print(dotnl)
 
// Blank line
print(nl)
 
// Skip to the top of the loop while the counter is >= 2
continue (c >= 2)
 
// At the last two
 
// "1 bottle of beer on the wall,"
a = 1
printnum()
print(bottle)
print(ofbeer)
print(wall)
print(sep)
 
// "1 bottle of beer."
a = 1
printnum()
print(bottle)
print(ofbeer)
print(dotnl)
 
// "Take one down and pass it around,"
print(takedown)
 
// "no more bottles of beer on the wall."
print(l_no)
print(more)
print(wall)
print(dotnl)
 
// Blank line
print(nl)
 
// "No more bottles of beer on the wall,"
print(u_no)
print(more)
print(wall)
print(sep)
 
// "no more bottles of beer."
print(l_no)
print(more)
print(dotnl)
 
// "Go to the store and buy some more,"
print(store)
 
// "99 bottles of beer on the wall."
a = 99
printnum()
print(bottle)
print(plural)
print(ofbeer)
print(wall)
print(dotnl)
end
end
 
// vim: set syntax=c ts=4 sw=4 et:
 

[edit] Befunge

See 99 Bottles of Beer/EsoLang

[edit] Bracmat

Copy the code to a file called BottlesOfBeer.bra. Start Bracmat and after the {?} prompt write get$"BottlesOfBeer.bra" <Enter>. Then, after the next prompt, write !r <Enter>. Notice that the lyrics has two more lines at the end:

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

Code to save to BottlesOfBeer.bra:

{BottlesOfBeer.bra
 
See http://99-bottles-of-beer.net/}
 
X=
new
= n upper nbottles lyrics
. 99:?n
& ( upper
= .@(!arg:%@?a ?z)&str$(upp$!a !z)
)
& ( nbottles
=
. str
$ ( (  !arg:>0
&  !arg
" bottle"
(!arg:1&|s)
| "no more bottles"
)
" of beer"
)
)
& ( lyrics
= (upper$(nbottles$!n:?x) " on the wall, " !x ".\n")
(  !n+-1:?n:~<0
& "Take one down and pass it around, "
nbottles$!n
" on the wall.
 
"
 !lyrics
| "Go to the store and buy some more, "
nbottles$99
" on the wall.
"
)
)
& put$(str$!lyrics);
 
r=
get'"BottlesOfBeer.bra"
& rmv$(str$(BottlesOfBeer ".bak"))
& ren$("BottlesOfBeer.bra".str$(BottlesOfBeer ".bak"))
& put
$ ( "{BottlesOfBeer.bra
 
See http://99-bottles-of-beer.net/}
 
"
, "BottlesOfBeer.bra"
, NEW
)
& lst'(X,"BottlesOfBeer.bra",APP)
& put'(\n,"BottlesOfBeer.bra",APP)
& lst'(r,"BottlesOfBeer.bra",APP)
& put$(str$("\nnew'" X ";\n"),"BottlesOfBeer.bra",APP);
 
new'X;
 

[edit] Brainf***

See 99 Bottles of Beer/EsoLang

[edit] Brat

99.to 2 { n |
p "#{n} bottles of beer on the wall, #{n} bottles of beer!"
p "Take one down, pass it around, #{n - 1} bottle#{true? n > 2 's' ''} of beer on the wall."
}
 
p "One bottle of beer on the wall, one bottle of beer!"
p "Take one down, pass it around, no more bottles of beer on the wall."

[edit] C

Translation of: C++

[edit] The simple solution

#include <stdlib.h>
#include <stdio.h>
 
int main(void)
{
unsigned int bottles = 99;
do
{
printf("%u bottles of beer on the wall\n", bottles);
printf("%u bottles of beer\n", bottles);
printf("Take one down, pass it around\n");
printf("%u bottles of beer on the wall\n\n", --bottles);
} while(bottles > 0);
return EXIT_SUCCESS;
}

[edit] A recursive solution

#include <stdio.h>
 
int main(int argc, char *argv[])
{
if(argc == 99)
return 99;
if(argv[0] != NULL){
argv[0] = NULL;
argc = 0;
}
argc = main(argc + 1, argv);
printf("%d bottle%c of beer on the wall\n", argc, argc == 1?'\0': 's');
printf("%d bottle%c of beer\n", argc, argc == 1?'\0': 's');
printf("Take one down, pass it around\n");
printf("%d bottle%c of beer on the wall\n\n", argc - 1, (argc - 1) == 1?'\0': 's');
return argc - 1;
}

[edit] Code golf

#include <stdio.h>
main(){_=100;while(--_)printf("%i bottle%s of beer in the wall,\n%i bottle%"
"s of beer.\nTake one down, pass it round,\n%s%s\n\n",_,_-1?"s":"",_,_-1?"s"
:"",_-1?(char[]){(_-1)/10?(_-1)/10+48:(_-1)%10+48,(_-1)/10?(_-1)%10+48:2+30,
(_-1)/10?32:0,0}:"",_-1?"bottles of beer in the wall":"No more beers");}

[edit] A preprocessor solution

Of course, with the template metaprogramming solution, the program has still do the conversion of numbers to strings at runtime, and those function calls also cost unnecessary time. Couldn't we just compose the complete text at compile time, and just output it at run time? Well, with the preprocessor, that's indeed possible:

#include <stdlib.h>
#include <stdio.h>
 
#define BOTTLE(nstr) nstr " bottles of beer"
 
#define WALL(nstr) BOTTLE(nstr) " on the wall"
 
#define PART1(nstr) WALL(nstr) "\n" BOTTLE(nstr) \
"\nTake one down, pass it around\n"

 
#define PART2(nstr) WALL(nstr) "\n\n"
 
#define MIDDLE(nstr) PART2(nstr) PART1(nstr)
 
#define SONG PART1("100") CD2 PART2("0")
 
#define CD2 CD3("9") CD3("8") CD3("7") CD3("6") CD3("5") \
CD3("4") CD3("3") CD3("2") CD3("1") CD4("")

 
#define CD3(pre) CD4(pre) MIDDLE(pre "0")
 
#define CD4(pre) MIDDLE(pre "9") MIDDLE(pre "8") MIDDLE(pre "7") \
MIDDLE(pre "6") MIDDLE(pre "5") MIDDLE(pre "4") MIDDLE(pre "3") \
MIDDLE(pre "2") MIDDLE(pre "1")

 
int main(void)
{
(void) printf(SONG);
return EXIT_SUCCESS;
}

An inspection of the generated executable proves that it indeed contains the complete text of the song in one block.

[edit] The bottled version

WYSIWYG (with correct plurals and can buy some more):
      int b =99,u =1;
#include<stdio.h>
char *d[16],y[]
= "#:ottle/ of"
":eer_ a_Go<o5"
"st>y\x20some6"
"_Take8;down4p"
"a=1rou7_17 _<"
"h;_ m?_nd_ on"
"_085wal" "l_ "
"b_e _ t_ss it"
"_?4bu_ore_9, "
"\060.""@, 9$";
# define x c ^=
#include <string.h>
#define or(t,z) else\
if(c==t && !(c = 0) &&\
(c =! z)); int p(char *t)

{ char *s = t; int c; for (
d[c = 0] = y; !t && (d[c +1
]= strchr(s = d[c], '_'));*
(d[++c]++) = 0); for(t = s?
s:t;(c= *s++); c && putchar
(c)) { if (!((( x 48)& ~0xf
) && ( x 48)) ) p(d[c]), c=
0 ; or('$', p(b - 99?".\n":
"." ) && p(b - 99? t : ""))
or ('\x40', c && p( d[!!b--
+ 2])) or('/', c && p( b^1?
"s": "")) or ('\043', b++ ?
p("So6" + --b):!printf("%d"
, b ? --b : (b += 99))) or(
'S',!(++u % 3) * 32+ 78) or
('.', puts("."))}return c;}
int main() {return p(0);}

[edit] C++

[edit] The simple solution

Works with: g++ version 4.8.1
#include <iostream>
using std::cout;
 
int main()
{
for(int bottles(99); bottles > 0; bottles -= 1){
cout << bottles << " bottles of beer on the wall\n"
<< bottles << " bottles of beer\n"
<< "Take one down, pass it around\n"
<< bottles - 1 << " bottles of beer on the wall\n\n";
}
}

[edit] An object-oriented solution

See: 99 Bottles of Beer/C++/Object Oriented

[edit] A template metaprogramming solution

Of course, the output of the program always looks the same. One may therefore question why the program has to do all that tedious subtracting during runtime. Couldn't the compiler just generate the code to output the text, with ready-calculated constants? Indeed, it can, and the technique is called template metaprogramming. The following short code gives the text without containing a single variable, let alone a loop:

#include <iostream>
 
template<int max, int min> struct bottle_countdown
{
static const int middle = (min + max)/2;
static void print()
{
bottle_countdown<max, middle+1>::print();
bottle_countdown<middle, min>::print();
}
};
 
template<int value> struct bottle_countdown<value, value>
{
static void print()
{
std::cout << value << " bottles of beer on the wall\n"
<< value << " bottles of beer\n"
<< "Take one down, pass it around\n"
<< value-1 << " bottles of beer\n\n";
}
};
 
int main()
{
bottle_countdown<100, 1>::print();
return 0;
}

[edit] A Recursive solution

#include <iostream>
using namespace std;
void rec(int bottles)
{
if ( bottles!=0)
{
cout << bottles << " bottles of beer on the wall" << endl;
cout << bottles << " bottles of beer" << endl;
cout << "Take one down, pass it around" << endl;
cout << --bottles << " bottles of beer on the wall\n" << endl;
rec(bottles);
}
}
 
int main()
{
rec(99);
system("pause");
return 0;
}
 

[edit] A preprocessor solution

Of course, with the template metaprogramming solution, the program has still do the conversion of numbers to strings at runtime, and those function calls also cost unnecessary time. Couldn't we just compose the complete text at compile time, and just output it at run time? Well, with the preprocessor, that's indeed possible:

#include <iostream>
#include <ostream>
 
#define BOTTLE(nstr) nstr " bottles of beer"
 
#define WALL(nstr) BOTTLE(nstr) " on the wall"
 
#define PART1(nstr) WALL(nstr) "\n" BOTTLE(nstr) \
"\nTake one down, pass it around\n"

 
#define PART2(nstr) WALL(nstr) "\n\n"
 
#define MIDDLE(nstr) PART2(nstr) PART1(nstr)
 
#define SONG PART1("100") CD2 PART2("0")
 
#define CD2 CD3("9") CD3("8") CD3("7") CD3("6") CD3("5") \
CD3("4") CD3("3") CD3("2") CD3("1") CD4("")

 
#define CD3(pre) CD4(pre) MIDDLE(pre "0")
 
#define CD4(pre) MIDDLE(pre "9") MIDDLE(pre "8") MIDDLE(pre "7") \
MIDDLE(pre "6") MIDDLE(pre "5") MIDDLE(pre "4") MIDDLE(pre "3") \
MIDDLE(pre "2") MIDDLE(pre "1")

 
int main()
{
std::cout << SONG;
return 0;
}

[edit] Bottled Version

                          //>,_
//Beer Song>,_
#include <iostream>
using namespace std;
int main(){ for( int
b=-1; b<99; cout <<
'\n') for ( int w=0;
w<3; cout << ".\n"){
if (w==2) cout << ((
b--) ?"Take one dow"
"n and pass it arou"
"nd":"Go to the sto"
"re and buy some mo"
"re"); if (b<0) b=99
; do{ if (w) cout <<
", "; if (b) cout <<
b; else cout << (
(w) ? 'n' : 'N') <<
"o more"; cout <<
" bottle" ; if
(b!=1) cout <<
's' ; cout <<
" of beer";
if (w!=1)
cout <<
" on th"
"e wall"
;} while
(!w++);}
return
0
;
}
//
// by barrym 2011-05-01
// no bottles were harmed in the
// making of this program!!!

[edit] C#

using System;
 
class Program
{
static void Main(string[] args)
{
for (int i = 99; i > -1; i--)
{
if (i == 0)
{
Console.WriteLine("No more bottles of beer on the wall, no more bottles of beer.");
Console.WriteLine("Go to the store and buy some more, 99 bottles of beer on the wall.");
break;
}
if (i == 1)
{
Console.WriteLine("1 bottle of beer on the wall, 1 bottle of beer.");
Console.WriteLine("Take one down and pass it around, no more bottles of beer on the wall.");
Console.WriteLine();
}
else
{
Console.WriteLine("{0} bottles of beer on the wall, {0} bottles of beer.", i);
Console.WriteLine("Take one down and pass it around, {0} bottles of beer on the wall.", i - 1);
Console.WriteLine();
}
}
}
}

[edit] Another Implementation using Linq

Works with: C# version 3+
using System;
using System.Linq;
 
class Program
{
static void Main()
{
var query = from total in Enumerable.Range(0,100).Reverse()
select (total > 0)
? string.Format("{0} bottles of beer on the wall\n{0} bottles of beer\nTake one down, pass it around", total)
: string.Format("{0} bottles left", total);
 
foreach (var item in query)
{
Console.WriteLine(item);
}
}
}

[edit] Flexible Version

 
class Program
{
const string Vessel = "bottle";
const string Beverage = "beer";
const string Location = "on the wall";
 
private static string DefaultAction(ref int bottles)
{
bottles--;
return "take one down, pass it around,";
}
 
private static string FallbackAction(ref int bottles)
{
bottles += 99;
return "go to the store, buy some more,";
}
 
private static string Act(ref int bottles)
{
return bottles > 0 ? DefaultAction(ref bottles) : FallbackAction(ref bottles);
}
 
static void Main()
{
Func<int, string> plural = b => b == 1 ? "" : "s";
Func<int, string> describeCount = b => b == 0 ? "no more" : b.ToString();
Func<int, string> describeBottles = b => string.Format("{0} {1}{2} of {3}", describeCount(b), Vessel, plural(b), Beverage);
Action<string> write = s => Console.WriteLine(CultureInfo.CurrentCulture.TextInfo.ToTitleCase(s));
int bottles = 99;
while (true)
{
write(string.Format("{0} {1}, {0},", describeBottles(bottles), Location));
write(Act(ref bottles));
write(string.Format("{0} {1}.", describeBottles(bottles), Location));
write(string.Empty);
}
}
}
 

[edit] Using Formatting

Works with: C# version 3+
 
class songs
{
static void Main(string[] args)
{
beer(5);
}
 
private static void beer(int bottles)
{
for (int i = bottles; i > 0; i--)
{
if (i > 1)
{
Console.Write("{0}\n{1}\n{2}\n{3}\n\n",
i + " bottles of beer on the wall",
i + " bottles of beer",
"Take one down, pass it around",
(i - 1) + " bottles of beer on the wall");
}
else
Console.Write("{0}\n{1}\n{2}\n{3}\n\n",
i + " bottle of beer on the wall",
i + " bottle of beer",
"Take one down, pass it around",
(i - 1) + " bottles of beer on the wall....");
}
}
}
Output:
5 bottles of beer on the wall
5 bottles of beer
Take one down, pass it around
4 bottles of beer on the wall

4 bottles of beer on the wall
4 bottles of beer
Take one down, pass it around
3 bottles of beer on the wall

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

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

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

[edit] Using iterator blocks

Works with: C# version 3+
using System;
using System.Linq;
 
class Program
{
static void Main()
{
BeerBottles().Take(99).ToList().ForEach(Console.WriteLine);
}
 
static IEnumerable<String> BeerBottles()
{
int i = 100;
String f = "{0}, {1}. Take one down, pass it around, {2}";
Func<int, bool, String> booze = (c , b) =>
String.Format("{0} bottle{1} of beer{2}", c > 0 ? c.ToString() : "no more", (c == 1 ? "" : "s"), b ? " on the wall" : "");
 
while (--i >= 1)
yield return String.Format(f, booze(i, true), booze(i, false), booze(i - 1, true));
}
}

[edit] A Fun One

 
string[] bottles = { "80 Shilling",
"Abita Amber",
"Adams Broadside Ale",
"Altenmünster Premium",
"August Schell's SnowStorm",
"Bah Humbug! Christmas Ale",
"Beck's Oktoberfest",
"Belhaven Wee Heavy",
"Bison Chocolate Stout",
"Blue Star Wheat Beer",
"Bridgeport Black Strap Stout",
"Brother Thelonius Belgian-Style Abbey Ale",
"Capital Blonde Doppelbock",
"Carta Blanca",
"Celis Raspberry Wheat",
"Christian Moerlein Select Lager",
"Corona",
"Czechvar",
"Delirium Tremens",
"Diamond Bear Southern Blonde",
"Don De Dieu",
"Eastside Dark",
"Eliot Ness",
"Flying Dog K-9 Cruiser Altitude Ale",
"Fuller's London Porter",
"Gaffel Kölsch",
"Golden Horseshoe",
"Guinness Pub Draught",
"Hacker-Pschorr Weisse",
"Hereford & Hops Black Spring Double Stout",
"Highland Oatmeal Porter",
"Ipswich Ale",
"Iron City",
"Jack Daniel's Amber Lager",
"Jamaica Sunset India Pale Ale",
"Killian's Red",
"König Ludwig Weiss",
"Kronenbourg 1664",
"Lagunitas Hairy Eyball Ale",
"Left Hand Juju Ginger",
"Locktender Lager",
"Magic Hat Blind Faith",
"Missing Elf Double Bock",
"Muskoka Cream Ale ",
"New Glarus Cherry Stout",
"Nostradamus Bruin",
"Old Devil",
"Ommegang Three Philosophers",
"Paulaner Hefe-Weizen Dunkel",
"Perla Chmielowa Pils",
"Pete's Wicked Springfest",
"Point White Biere",
"Prostel Alkoholfrei",
"Quilmes",
"Rahr's Red",
"Rebel Garnet",
"Rickard's Red",
"Rio Grande Elfego Bock",
"Rogue Brutal Bitter",
"Roswell Alien Amber Ale",
"Russian River Pliny The Elder",
"Samuel Adams Blackberry Witbier",
"Samuel Smith's Taddy Porter",
"Schlafly Pilsner",
"Sea Dog Wild Blueberry Wheat Ale",
"Sharp's",
"Shiner 99",
"Sierra Dorada",
"Skullsplitter Orkney Ale",
"Snake Chaser Irish Style Stout",
"St. Arnold Bock",
"St. Peter's Cream Stout",
"Stag",
"Stella Artois",
"Stone Russian Imperial Stout",
"Sweetwater Happy Ending Imperial Stout",
"Taiwan Gold Medal",
"Terrapin Big Hoppy Monster",
"Thomas Hooker American Pale Ale",
"Tie Die Red Ale",
"Toohey's Premium",
"Tsingtao",
"Ugly Pug Black Lager",
"Unibroue Qatre-Centieme",
"Victoria Bitter",
"Voll-Damm Doble Malta",
"Wailing Wench Ale",
"Warsteiner Dunkel",
"Wellhead Crude Oil Stout",
"Weyerbacher Blithering Idiot Barley-Wine Style Ale",
"Wild Boar Amber",
"Würzburger Oktoberfest",
"Xingu Black Beer",
"Yanjing",
"Younger's Tartan Special",
"Yuengling Black & Tan",
"Zagorka Special",
"Zig Zag River Lager",
"Zywiec" };
 
 
int bottlesLeft = 99;
const int FIRST_LINE_SINGULAR = 98;
const int FINAL_LINE_SINGULAR = 97;
string firstLine = "";
string finalLine = "";
 
 
for (int i = 0; i < 99; i++)
{
firstLine = bottlesLeft.ToString() + " bottle";
if (i != FIRST_LINE_SINGULAR)
firstLine += "s";
firstLine += " of beer on the wall, " + bottlesLeft.ToString() + " bottle";
if (i != FIRST_LINE_SINGULAR)
firstLine += "s";
firstLine += " of beer";
 
Console.WriteLine(firstLine);
Console.WriteLine("Take the " + bottles[i] + " down, pass it around,");
bottlesLeft--;
 
finalLine = bottlesLeft.ToString() + " bottle";
if (i != FINAL_LINE_SINGULAR)
finalLine += "s";
finalLine += " of beer on the wall!";
 
Console.WriteLine(finalLine);
Console.WriteLine();
Console.ReadLine();
}
 

[edit] Using recursion

 
public static void BottlesSong(int numberOfBottles)
{
if (numberOfBottles > 0)
{
Console.WriteLine("{0} bottles of beer on the wall", numberOfBottles);
Console.WriteLine("{0} bottles of beer ", numberOfBottles);
Console.WriteLine("Take one down, pass it around");
Console.WriteLine("{0} bottles of beer ", numberOfBottles - 1);
Console.WriteLine();
BottlesSong(--numberOfBottles);
}
}
 

[edit] Clay

/* A few options here: I could give n type Int; or specify that n is of any
numeric type; but here I just let it go -- that way it'll work with anything
that compares with 1 and that printTo knows how to convert to a string. And
all checked at compile time, remember. */
getRound(n) {
var s = String();
var bottle = if (n == 1) " bottle " else " bottles ";
 
printTo(s,
n, bottle, "of beer on the wall\n",
n, bottle, "of beer\n",
"take one down, pass it around\n",
n, bottle, "of beer on the wall!\n");
 
return s;
}
 
main() {
println(join("\n", mapped(getRound, reversed(range(100)))));
}
 

[edit] Chapel

copied from http://99-bottles-of-beer.net/language-chapel-1215.html, with minor modifications for chapel 1.7

Works with: Chapel version 1.7.0
 
/***********************************************************************
* Chapel implementation of "99 bottles of beer"
*
* by Brad Chamberlain and Steve Deitz
* 07/13/2006 in Knoxville airport while waiting for flight home from
* HPLS workshop
* compiles and runs with chpl compiler version 1.7.0
* for more information, contact: [email protected]
*
*
* Notes:
* o as in all good parallel computations, boundary conditions
* constitute the vast bulk of complexity in this code (invite Brad to
* tell you about his zany boundary condition simplification scheme)
* o uses type inference for variables, arguments
* o relies on integer->string coercions
* o uses named argument passing (for documentation purposes only)
***********************************************************************/
 
// allow executable command-line specification of number of bottles
// (e.g., ./a.out -snumBottles=999999)
config const numBottles = 99;
const numVerses = numBottles+1;
 
// a domain to describe the space of lyrics
var LyricsSpace: domain(1) = {1..numVerses};
 
// array of lyrics
var Lyrics: [LyricsSpace] string;
 
// parallel computation of lyrics array
[verse in LyricsSpace] Lyrics(verse) = computeLyric(verse);
 
// as in any good parallel language, I/O to stdout is serialized.
// (Note that I/O to a file could be parallelized using a parallel
// prefix computation on the verse strings' lengths with file seeking)
writeln(Lyrics);
 
 
// HELPER FUNCTIONS:
 
proc computeLyric(verseNum) {
var bottleNum = numBottles - (verseNum - 1);
var nextBottle = (bottleNum + numVerses - 1)%numVerses;
return "\n" // disguise space used to separate elements in array I/O
+ describeBottles(bottleNum, startOfVerse=true) + " on the wall, "
+ describeBottles(bottleNum) + ".\n"
+ computeAction(bottleNum)
+ describeBottles(nextBottle) + " on the wall.\n";
}
 
 
proc describeBottles(bottleNum, startOfVerse:bool = false) {
// NOTE: bool should not be necessary here (^^^^); working around bug
var bottleDescription = if (bottleNum) then bottleNum:string
else (if startOfVerse then "N"
else "n")
+ "o more";
return bottleDescription
+ " bottle" + (if (bottleNum == 1) then "" else "s")
+ " of beer";
}
 
 
proc computeAction(bottleNum) {
return if (bottleNum == 0) then "Go to the store and buy some more, "
else "Take one down and pass it around, ";
}
 

[edit] Chef

See 99 Bottles of Beer/EsoLang

[edit] CLIPS

(deffacts beer-bottles
(bottles 99))
 
(deffunction bottle-count
(?count)
(switch ?count
(case 0 then "No more bottles of beer")
(case 1 then "1 more bottle of beer")
(default (str-cat ?count " bottles of beer"))))
 
(defrule stanza
 ?bottles <- (bottles ?count)
=>
(retract ?bottles)
(printout t (bottle-count ?count) " on the wall," crlf)
(printout t (bottle-count ?count) "." crlf)
(printout t "Take one down, pass it around," crlf)
(printout t (bottle-count (- ?count 1)) " on the wall." crlf crlf)
(if (> ?count 1) then (assert (bottles (- ?count 1)))))

[edit] Clojure

(defn sing
[start]
(doseq [n (range start 0 -1)]
(printf "%d bottles of beer on the wall,
%d bottles of beer,
Take one down, pass it around,
%d bottles of beer on the wall.\n\n"

n
n
(dec n))))
 
(sing 99)

Or, using cl-format:

Translation of: Common Lisp
(clojure.pprint/cl-format 
true
"~{~[~^~]~:*~D bottle~:P of beer on the wall~%~:*~D bottle~:P of beer
Take one down, pass it around,~%~D bottle~:P~:* of beer on the wall.~2%~}"

(range 99 0 -1))

[edit] COBOL

Works with: OpenCOBOL version 1.1

Free form version.

identification division.
program-id. ninety-nine.
environment division.
data division.
working-storage section.
01 counter pic 99.
88 no-bottles-left value 0.
88 one-bottle-left value 1.
 
01 parts-of-counter redefines counter.
05 tens pic 9.
05 digits pic 9.
 
01 after-ten-words.
05 filler pic x(7) value spaces.
05 filler pic x(7) value "Twenty".
05 filler pic x(7) value "Thirty".
05 filler pic x(7) value "Forty".
05 filler pic x(7) value "Fifty".
05 filler pic x(7) value "Sixty".
05 filler pic x(7) value "Seventy".
05 filler pic x(7) value "Eighty".
05 filler pic x(7) value "Ninety".
05 filler pic x(7) value spaces.
 
01 after-ten-array redefines after-ten-words.
05 atens occurs 10 times pic x(7).
 
01 digit-words.
05 filler pic x(9) value "One".
05 filler pic x(9) value "Two".
05 filler pic x(9) value "Three".
05 filler pic x(9) value "Four".
05 filler pic x(9) value "Five".
05 filler pic x(9) value "Six".
05 filler pic x(9) value "Seven".
05 filler pic x(9) value "Eight".
05 filler pic x(9) value "Nine".
05 filler pic x(9) value "Ten".
05 filler pic x(9) value "Eleven".
05 filler pic x(9) value "Twelve".
05 filler pic x(9) value "Thirteen".
05 filler pic x(9) value "Fourteen".
05 filler pic x(9) value "Fifteen".
05 filler pic x(9) value "Sixteen".
05 filler pic x(9) value "Seventeen".
05 filler pic x(9) value "Eighteen".
05 filler pic x(9) value "Nineteen".
05 filler pic x(9) value spaces.
 
01 digit-array redefines digit-words.
05 adigits occurs 20 times pic x(9).
 
01 number-name pic x(15).
 
procedure division.
100-main section.
100-setup.
perform varying counter from 99 by -1 until no-bottles-left
perform 100-show-number
display " of beer on the wall"
perform 100-show-number
display " of beer"
display "Take " with no advancing
if one-bottle-left
display "it " with no advancing
else
display "one " with no advancing
end-if
display "down and pass it round"
subtract 1 from counter giving counter
perform 100-show-number
display " of beer on the wall"
add 1 to counter giving counter
display space
end-perform.
display "No more bottles of beer on the wall"
display "No more bottles of beer"
display "Go to the store and buy some more"
display "Ninety Nine bottles of beer on the wall"
stop run.
 
100-show-number.
if no-bottles-left
display "No more" with no advancing
else
if counter < 20
display function trim( adigits( counter ) ) with no advancing
else
if counter < 100
move spaces to number-name
string atens( tens ) delimited by space, space delimited by size, adigits( digits ) delimited by space into number-name
display function trim( number-name) with no advancing
end-if
end-if
end-if.
if one-bottle-left
display " bottle" with no advancing
else
display " bottles" with no advancing
end-if.
 
100-end.
end-program.

Another free-form version, without using DISPLAY NO ADVANCING.

identification division.
program-id. ninety-nine.
environment division.
data division.
working-storage section.
01 counter pic 99.
88 no-bottles-left value 0.
88 one-bottle-left value 1.
 
01 parts-of-counter redefines counter.
05 tens pic 9.
05 digits pic 9.
 
01 after-ten-words.
05 filler pic x(7) value spaces.
05 filler pic x(7) value "Twenty".
05 filler pic x(7) value "Thirty".
05 filler pic x(7) value "Forty".
05 filler pic x(7) value "Fifty".
05 filler pic x(7) value "Sixty".
05 filler pic x(7) value "Seventy".
05 filler pic x(7) value "Eighty".
05 filler pic x(7) value "Ninety".
05 filler pic x(7) value spaces.
 
01 after-ten-array redefines after-ten-words.
05 atens occurs 10 times pic x(7).
 
01 digit-words.
05 filler pic x(9) value "One".
05 filler pic x(9) value "Two".
05 filler pic x(9) value "Three".
05 filler pic x(9) value "Four".
05 filler pic x(9) value "Five".
05 filler pic x(9) value "Six".
05 filler pic x(9) value "Seven".
05 filler pic x(9) value "Eight".
05 filler pic x(9) value "Nine".
05 filler pic x(9) value "Ten".
05 filler pic x(9) value "Eleven".
05 filler pic x(9) value "Twelve".
05 filler pic x(9) value "Thirteen".
05 filler pic x(9) value "Fourteen".
05 filler pic x(9) value "Fifteen".
05 filler pic x(9) value "Sixteen".
05 filler pic x(9) value "Seventeen".
05 filler pic x(9) value "Eighteen".
05 filler pic x(9) value "Nineteen".
05 filler pic x(9) value spaces.
 
01 digit-array redefines digit-words.
05 adigits occurs 20 times pic x(9).
 
01 number-name pic x(15).
 
01 stringified pic x(30).
01 outline pic x(50).
01 other-numbers.
03 n pic 999.
03 r pic 999.
 
procedure division.
100-main section.
100-setup.
perform varying counter from 99 by -1 until no-bottles-left
move spaces to outline
perform 100-show-number
string stringified delimited by "|", space, "of beer on the wall" into outline end-string
display outline end-display
move spaces to outline
string stringified delimited by "|", space, "of beer" into outline end-string
display outline end-display
move spaces to outline
move "Take" to outline
if one-bottle-left
string outline delimited by space, space, "it" delimited by size, space, "|" into outline end-string
else
string outline delimited by space, space, "one" delimited by size, space, "|" into outline end-string
end-if
string outline delimited by "|", "down and pass it round" delimited by size into outline end-string
display outline end-display
move spaces to outline
subtract 1 from counter giving counter end-subtract
perform 100-show-number
string stringified delimited by "|", space, "of beer on the wall" into outline end-string
display outline end-display
add 1 to counter giving counter end-add
display space end-display
end-perform.
display "No more bottles of beer on the wall"
display "No more bottles of beer"
display "Go to the store and buy some more"
display "Ninety-Nine bottles of beer on the wall"
stop run.
 
100-show-number.
if no-bottles-left
move "No more|" to stringified
else
if counter < 20
string function trim( adigits( counter ) ), "|" into stringified
else
if counter < 100
move spaces to number-name
string atens( tens ) delimited by space, space delimited by size, adigits( digits ) delimited by space into number-name end-string
move function trim( number-name) to stringified
divide counter by 10 giving n remainder r end-divide
if r not = zero
inspect stringified replacing first space by "-"
end-if
inspect stringified replacing first space by "|"
end-if
end-if
end-if.
if one-bottle-left
string stringified delimited by "|", space, "bottle|" delimited by size into stringified end-string
else
string stringified delimited by "|", space, "bottles|" delimited by size into stringified end-string
end-if.
 
100-end.
end-program.

A more concise version that adheres to the minimum guidelines. Leading zeros are not suppressed. (OpenCOBOL - 1.1.0)

program-id. ninety-nine.
data division.
working-storage section.
01 cnt pic 99.
 
procedure division.
 
perform varying cnt from 99 by -1 until cnt < 1
display cnt " bottles of beer on the wall"
display cnt " bottles of beer"
display "Take one down, pass it around"
subtract 1 from cnt
display cnt " bottles of beer on the wall"
add 1 to cnt
display space
end-perform.

[edit] CoffeeScript

 
bottlesOfBeer = (n) ->
"#{n} bottle#{if n is 1 then '' else 's'} of beer"
 
console.log """
#{bottlesOfBeer n} on the wall
#{bottlesOfBeer n}
Take one down, pass it around
#{bottlesOfBeer n - 1} on the wall
\n"""
for n in [99..1]
 

With completely different approach...

for j in [99..1]
x=''
x += [j,j-1,'\nTake one down, pass it around\n'," bottles of beer",' on the wall\n'][i] for i in [0,3,4,0,3,2,1,3,4]
console.log x.replace /(1.+)s/g, '$1'
 

or as a one liner...

console.log( if (j+2)%4 then (x=Math.round j/4)+" bottle#{if x-1 then 's' else ''} of beer#{if (j+1)%4 then ' on the wall' else ''}" else "Take one down, pass it around" ) for j in [396..1]

or another completely different one liner

((console.log if i is 2 then "Take one down, pass it around" else "#{b-!(i-1%4)} bottle#{if 4*b+i<10 and b-i then '' else 's'} of beer#{if i%3 then ' on the wall' else ''}") for i in [4..1]) for b in [99..1]

[edit] ColdFusion

[edit] Classic tag based CFML

<cfoutput>
<cfloop index="x" from="99" to="0" step="-1">
<cfset plur = iif(x is 1,"",DE("s"))>
#x# bottle#plur# of beer on the wall<br>
#x# bottle#plur# of beer<br>
Take one down, pass it around<br>
#iif(x is 1,DE("No more"),"x-1")# bottle#iif(x is 2,"",DE("s"))# of beer on the wall<br><br>
</cfloop>
</cfoutput>

or if you prefer: (identical output, grammatically correct to the last stanza)

[edit] CFScript

<cfscript>
for (x=99; x gte 1; x--) {
plur = iif(x==1,'',DE('s'));
WriteOutput("#x# bottle#plur# of beer on the wall<br>#x# bottle#plur# of beer<br>Take one down, pass it around<br>#iif(x is 1,DE('No more'),'x-1')# bottle#iif(x is 2,'',DE('s'))# of beer on the wall<br><br>");
}
</cfscript>

[edit] Common Lisp

See 99 Bottles of Beer/Lisp

[edit] Component Pascal

See 99 Bottles of Beer/Pascal

[edit] D

[edit] Simple Solution

Works with: D version 2

Based on Steward Gordon's code at: 99-bottles-of-beer.net.

import std.stdio;
 
void main() {
int bottles = 99;
 
while (bottles > 1) {
writeln(bottles, " bottles of beer on the wall,");
writeln(bottles, " bottles of beer.");
writeln("Take one down, pass it around,");
if (--bottles > 1) {
writeln(bottles, " bottles of beer on the wall.\n");
}
}
writeln("1 bottle of beer on the wall.\n");
 
writeln("No more bottles of beer on the wall,");
writeln("no more bottles of beer.");
writeln("Go to the store and buy some more,");
writeln("99 bottles of beer on the wall.");
}

[edit] CTFE Solution

CTFE (Compile-Time Function Execution) is a feature of D that allows for pure functions of arbitrary complexity to be completely evaluated at compile time when every parameter is known. Note that this is distinct from the template meta-programming tricks used by some other languages, and this bottles() function could just as easily be executed during run-time. The compiled result of this program simply prints the pre-generated lyrics to the song, using a standard compiler pragma directive.

import std.stdio, std.conv;
 
string bottles(in size_t num) pure {
static string bottlesRecurse(in size_t num) pure {
return num.text ~ " bottles of beer on the wall,\n"
~ num.text ~ " bottles of beer!\n"
~ "Take one down, pass it around,\n"
~ (num - 1).text ~ " bottle" ~ ((num - 1 == 1) ? "" : "s")
~ " of beer on the wall.\n\n"
~ ((num > 2)
? bottlesRecurse(num - 1)
: "1 bottle of beer on the wall,\n"
~ "1 bottle of beer!\n"
~ "Take one down, pass it around,\n"
~ "No bottles of beer on the wall!\n\n");
}
 
return bottlesRecurse(num)
~ "Go to the store and buy some more...\n"
~ num.text ~ " bottles of beer on the wall!";
}
 
pragma(msg, 99.bottles);
void main() {}

[edit] Dart

main() {
for(int x=99;x>0;x--) {
print("$x bottles of beer on the wall");
print("$x bottles of beer");
print("Take one down, pass it around");
print("${x-1} bottles of beer on the wall");
print("");
}
}

[edit] Delphi

See 99 Bottles of Beer/Pascal

[edit] Déjà Vu

plural i:
if = 1 i "" "s"
 
bottles i:
local :s plural i
!print( to-str i " bottle"s" of beer on the wall, " to-str i " bottle"s" of beer," )
!print\ "You take one down, pass it around, "
set :i -- i
if i:
set :s plural i
!print( to-str i " bottle"s" of beer on the wall." )
bottles i
else:
!print "no more bottles of beer on the wall, no more bottles of beer."
!print "Go to the store and buy some more, 99 bottles of beer on the wall."
 
bottles 99

[edit] Dylan

Module: bottles
define method bottles (n :: <integer>)
for (n from 99 to 1 by -1)
format-out("%d bottles of beer on the wall,\n"
"%d bottles of beer\n"
"Take one down, pass it around\n"
"%d bottles of beer on the wall\n",
n, n, n - 1);
end
end method

[edit] E

def bottles(n) {
return switch (n) {
match ==0 { "No bottles" }
match ==1 { "1 bottle" }
match _ { `$n bottles` }
}
}
for n in (1..99).descending() {
println(`${bottles(n)} of beer on the wall,
${bottles(n)} of beer.
Take one down, pass it around,
${bottles(n.previous())} of beer on the wall.
`
)
}

[edit] ECL

 
Layout := RECORD
UNSIGNED1 RecID1;
UNSIGNED1 RecID2;
STRING30 txt;
END;
Beers := DATASET(99,TRANSFORM(Layout,
SELF.RecID1 := COUNTER,SELF.RecID2 := 0,SELF.txt := ''));
 
Layout XF(Layout L,INTEGER C) := TRANSFORM
IsOneNext := L.RecID1-1 = 1;
IsOne := L.RecID1 = 1;
SELF.txt := CHOOSE(C,
(STRING)(L.RecID1-1) + ' bottle'+IF(IsOneNext,'','s')+' of beer on the wall',
'Take one down, pass it around',
(STRING)(L.RecID1) + ' bottle'+IF(IsOne,'','s')+' of beer',
(STRING)(L.RecID1) + ' bottle'+IF(IsOne,'','s')+' of beer on the wall','');
SELF.RecID2 := C;
SELF := L;
END;
 
Rev := NORMALIZE(Beers,5,XF(LEFT,COUNTER));
OUTPUT(SORT(Rev,-Recid1,-RecID2),{txt},ALL);
 

[edit] EGL

program TestProgram type BasicProgram {}
 
function main()
for (count int from 99 to 1 decrement by 1)
SysLib.writeStdout( bottleStr( count ) :: " of beer on the wall." );
SysLib.writeStdout( bottleStr( count ) :: " of beer." );
SysLib.writeStdout( "Take one down, pass it around." );
SysLib.writeStdout( bottleStr( count - 1) :: " of beer on the wall.\n");
end
end
 
private function bottleStr( count int in) returns( string )
case ( count )
when ( 1 )
return( "1 bottle" );
when ( 0 )
return( "No more bottles" );
otherwise
return( count :: " bottles" );
end
end
end

[edit] Eiffel

 
class
APPLICATION
 
create
make
 
feature {NONE} -- Initialization
 
make
local
bottles: INTEGER
do
from
bottles := 99
invariant
bottles <= 99 and bottles >= 1
until
bottles = 1
loop
print (bottles)
print (" bottles of beer on the wall,%N")
print (bottles)
print (" bottles of beer.%N")
print ("Take one down, pass it around,%N")
bottles := bottles - 1
if bottles > 1 then
print (bottles)
print (" bottles of beer on the wall.%N%N")
end
variant
bottles
end
print ("1 bottle of beer on the wall.%N%N");
print ("No more bottles of beer on the wall,%N");
print ("no more bottles of beer.%N");
print ("Go to the store and buy some more,%N");
print ("99 bottles of beer on the wall.%N");
end
 
end
 

[edit] Ela

open list
 
beer 1 = "1 bottle of beer on the wall\n1 bottle of beer\nTake one down, pass it around"
beer 0 = "better go to the store and buy some more."
beer v = show v ++ " bottles of beer on the wall\n"
++ show v
++" bottles of beer\nTake one down, pass it around\n"
 
map beer [99,98..0]

[edit] Elixir

defmodule Bottles do
def run do
Enum.each 99..1, fn idx ->
IO.puts "#{idx} bottle#{plural(idx)} of beer on the wall"
IO.puts "#{idx} bottle#{plural(idx)} of beer"
IO.puts "Take one down, pass it around"
IO.puts "#{idx - 1} bottle#{plural(idx-1)} of beer on the wall"
IO.puts ""
end
end
 
def plural(1), do: ""
def plural(num), do: "s"
end
 
Bottles.run

[edit] Erlang

-module(beersong).
-export([sing/0]).
-define(TEMPLATE_0, "~s of beer on the wall, ~s of beer.~nGo to the store and buy some more, 99
bottles of beer on the wall.~n"
).
-define(TEMPLATE_N, "~s of beer on the wall, ~s of beer.~nTake one down and pass it around, ~s of
beer on the wall.~n~n"
).
 
create_verse(0) -> {0, io_lib:format(?TEMPLATE_0, phrase(0))};
create_verse(Bottle) -> {Bottle, io_lib:format(?TEMPLATE_N, phrase(Bottle))}.
 
phrase(0) -> ["No more bottles", "no more bottles"];
phrase(1) -> ["1 bottle", "1 bottle", "no more bottles"];
phrase(2) -> ["2 bottles", "2 bottles", "1 bottle"];
phrase(Bottle) -> lists:duplicate(2, integer_to_list(Bottle) ++ " bottles") ++
[integer_to_list(Bottle-1) ++ " bottles"].
 
bottles() -> lists:reverse(lists:seq(0,99)).
 
sing() ->
lists:foreach(fun spawn_singer/1, bottles()),
sing_verse(99).
 
spawn_singer(Bottle) ->
Pid = self(),
spawn(fun() -> Pid ! create_verse(Bottle) end).
 
sing_verse(Bottle) ->
receive
{_, Verse} when Bottle == 0 ->
io:format(Verse);
{N, Verse} when Bottle == N ->
io:format(Verse),
sing_verse(Bottle-1)
after
3000 ->
io:format("Verse not received - re-starting singer~n"),
spawn_singer(Bottle),
sing_verse(Bottle)
end.

[edit] Euphoria

Works with: Euphoria version 4.0.0

This is based on the Batch File example.

 
include std/console.e
include std/search.e
 
function one_or_it( atom n )
if n = 1 then
return "it"
else
return "one"
end if
end function
 
function numberable( atom n )
if n = 0 then
return "no"
else
return sprintf( "%d", n )
end if
end function
 
function plural( atom n )
if n != 1 then
return "s"
else
return ""
end if
end function
 
atom stillDrinking = 1
 
sequence yn
sequence plurality
sequence numerality
 
while stillDrinking do
for bottle = 99 to 1 by -1 do
plurality = plural( bottle )
numerality = numberable( bottle )
printf( 1, "%s bottle%s of beer on the wall\n%s bottle%s of beer\n",
{ numerality, plurality, numerality, plurality } )
printf( 1, "Take %s down and pass it round\n", { one_or_it( bottle ) } )
printf( 1, "%s bottle%s of beer on the wall\n\n",
{ numberable( bottle - 1 ), plural( bottle - 1 ) } )
end for
puts( 1, "No more bottles of beer on the wall\nNo more bottles of beer\n" )
puts( 1, "Go to the store and buy some more\n99 bottles of beer on the wall\n" )
puts( 1, "\nKeep drinking? " )
yn = gets(0)
stillDrinking = find_any( "yY", yn )
puts( 1, "\n" )
end while

[edit] Extended BrainF***

See 99 Bottles of Beer/EsoLang

[edit] F#

#light
let rec bottles n =
let (before, after) = match n with
| 1 -> ("bottle", "bottles")
| 2 -> ("bottles", "bottle")
| n -> ("bottles", "bottles")
printfn "%d %s of beer on the wall" n before
printfn "%d %s of beer" n before
printfn "Take one down, pass it around"
printfn "%d %s of beer on the wall\n" (n - 1) after
if n > 1 then
bottles (n - 1)

[edit] Factor

USING: io kernel make math math.parser math.ranges sequences ;
 
: bottle ( -- quot )
[
[
[
[ # " bottles of beer on the wall,\n" % ]
[ # " bottles of beer.\n" % ] bi
] keep
"Take one down, pass it around,\n" %
1 - # " bottles of beer on the wall\n" %
] " " make print
] ; inline
 
: last-verse ( -- )
"Go to the store and buy some more,"
"no more bottles of beer on the wall!" [ print ] bi@ ;
 
: bottles ( n -- )
1 [a,b] bottle each last-verse ;
 
! Usage: 99 bottles

[edit] Falcon

for i in [99:1]
> i, " bottles of beer on the wall"
> i, " bottles of beer"
> "Take one down, pass it around"
> i-1, " bottles of beer on the wall\n"
end

A more robust version to handle plural/not plural conditions

for i in [99:1]
plural = (i != 1) ? 's' : ""
> @ "$i bottle$plural of beer on the wall"
> @ "$i bottle$plural of beer"
> "Take one down, pass it around"
> i-1, @ " bottle$plural of beer on the wall\n"
end

[edit] FALSE

See 99 Bottles of Beer/EsoLang

[edit] ferite

copied from 99-bottles-of-beer.net.

uses "console";
 
number bottles = 99;
boolean looping = true;
object counter = closure {
if (--bottles > 0) {
return true;
} else {
return false;
}
};
 
while (looping) {
Console.println("${bottles} bottles of beer on the wall,");
Console.println("${bottles} bottles of beer,");
Console.println("Take one down, pass it around,");
 
looping = counter.invoke();
 
Console.println("${bottles} bottles of beer on the wall.");

[edit] Fexl

 
\suffix=(\n eq n 1 "" "s")
\sing_count=(\n put n put " " put "bottle" put (suffix n) put " of beer")
\sing_line1=(\n sing_count n put " on the wall" nl)
\sing_line2=(\n sing_count n nl)
\sing=
(@\loop\n
le n 0 ();
sing_line1 n
sing_line2 n
say "Take one down, pass it around"
\n=(- n 1)
sing_line1 n
nl
loop n
)
sing 3
 
Output:
3 bottles of beer on the wall
3 bottles of beer
Take one down, pass it around
2 bottles of beer on the wall

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

1 bottle of beer on the wall
1 bottle of beer
Take one down, pass it around
0 bottles of beer on the wall

[edit] Forth

:noname   dup . ." bottles" ;
:noname ." 1 bottle"  ;
:noname ." no more bottles" ;
create bottles , , ,
 
: .bottles dup 2 min cells bottles + @ execute ;
: .beer .bottles ." of beer" ;
: .wall .beer ." on the wall" ;
: .take ." Take one down, pass it around" ;
: .verse .wall cr .beer cr
1- .take cr .wall cr ;
: verses begin cr .verse ?dup 0= until ;
 
99 verses

[edit] Fortran

program bottlestest
 
implicit none
 
integer :: i
 
character(len=*), parameter :: bwall = " on the wall", &
bottles = "bottles of beer", &
bottle = "bottle of beer", &
take = "Take one down, pass it around", &
form = "(I0, ' ', A)"
 
do i = 99,0,-1
if ( i /= 1 ) then
write (*,form) i, bottles // bwall
if ( i > 0 ) write (*,form) i, bottles
else
write (*,form) i, bottle // bwall
write (*,form) i, bottle
end if
if ( i > 0 ) write (*,*) take
end do
 
end program bottlestest

[edit] MPI version

program bottlesMPI
 
implicit none
 
integer :: ierr,rank,nproc
 
character(len=*), parameter :: bwall = " on the wall", &
bottles = "bottles of beer", &
bottle = "bottle of beer", &
take = "Take one down, pass it around", &
form = "(I0, ' ', A)"
 
call mpi_init(ierr)
call mpi_comm_size(MPI_COMM_WORLD,nproc, ierr)
call mpi_comm_rank(MPI_COMM_WORLD,rank,ierr)
 
if ( rank /= 1 ) then
write (*,form) rank, bottles // bwall
if ( rank > 0 ) write (*,form) rank, bottles
else
write (*,form) rank, bottle // bwall
write (*,form) rank, bottle
end if
if ( rank > 0 ) write (*,*) take
 
call mpi_finalize(ierr)
 
end program bottlesMPI

Usage:

mpif90 filename.f90
mpiexec -np 99 a.out

[edit] Frege

Translation of: Haskell
(identical to the Haskell, apart from adding the module declaration)
Works with: Frege version 3.21.586-g026e8d7
module Beer where
 
main = mapM_ (putStrLn . beer) [99, 98 .. 0]
beer 1 = "1 bottle of beer on the wall\n1 bottle of beer\nTake one down, pass it around"
beer 0 = "better go to the store and buy some more."
beer v = show v ++ " bottles of beer on the wall\n"
++ show v
++ " bottles of beer\nTake one down, pass it around\n"
++ head (lines $ beer $ v-1) ++ "\n"

[edit] friendly interactive shell

See 99 Bottles of Beer/Shell

[edit] Frink

Frink tracks units of measure through all calculations. It has a large library of built-in units of measure, including volume. The following program prints out the remaining volume of beer (assuming we start with 99 bottles of beer, each containing 12 fluid ounces) in different random units of volume, never repeating a unit.

 
units = array[units[volume]]
showApproximations[false]
 
for n = 99 to 0 step -1
{
unit = units.removeRandom[]
str = getBottleString[n, unit]
 
println["$str of beer on the wall, $str."]
 
if (n == 0)
println["Go to the store and buy some more, 99 bottles of beer on the wall."]
else
println["Take one down and pass it around, " + getBottleString[n-1, unit] + " on the wall.\n"]
}
 
getBottleString[n, unit] := format[n*12 floz, unit, 6] + "s"
 

Sample randomized output:

0.019386 facecords of beer on the wall, 0.019386 facecords.
Take one down and pass it around, 0.019190 facecords on the wall.

36.750000 quarts of beer on the wall, 36.750000 quarts.
Take one down and pass it around, 36.375000 quarts on the wall.

581539.650545 brminims of beer on the wall, 581539.650545 brminims.
Take one down and pass it around, 575544.396416 brminims on the wall.

10.377148 scotsoatlippys of beer on the wall, 10.377148 scotsoatlippys.
Take one down and pass it around, 10.269053 scotsoatlippys on the wall.

7.416004 cangallons of beer on the wall, 7.416004 cangallons.
Take one down and pass it around, 7.337941 cangallons on the wall.

3335.894135 dessertspoons of beer on the wall, 3335.894135 dessertspoons.
Take one down and pass it around, 3300.405899 dessertspoons on the wall.

0.233105 barrelbulks of beer on the wall, 0.233105 barrelbulks.
Take one down and pass it around, 0.230599 barrelbulks on the wall.

21.766118 magnums of beer on the wall, 21.766118 magnums.
Take one down and pass it around, 21.529530 magnums on the wall.

1092.000000 fluidounces of beer on the wall, 1092.000000 fluidounces.
Take one down and pass it around, 1080.000000 fluidounces on the wall.
...
12.000000 ponys of beer on the wall, 12.000000 ponys.
Take one down and pass it around, 0.000000 ponys on the wall.

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

[edit] FunL

val
numbers = {1:'one', 2:'two', 3:'three', 4:'four', 5:'five', 6:'six', 7:'seven',
8:'eight', 9:'nine', 10:'ten', 11:'eleven', 12:'twelve'}
alt = {3:'thir', 5:'fif'}
 
def
suffix( a, b ) = (if a.endsWith( 't' ) then a.substring( 0, a.length()-1 ) else a) + b
 
number( n@(13 | 15) ) = suffix( alt(n%10), 'teen' )
number( 20 ) = 'twenty'
number( n@(30 | 50) ) = suffix( alt(n\10), 'ty' )
number( n )
| n <= 12 = numbers(n)
| n <= 19 = suffix( numbers(n%10), 'teen' )
| 10|n = suffix( numbers(n\10), 'ty' )
| otherwise = number( n\10*10 ) + '-' + number( n%10 )
 
cap( s ) = s.substring( 0, 1 ).toUpperCase() + s.substring( 1, s.length() )
 
bottles( 0 ) = 'no more bottles'
bottles( 1 ) = 'one bottle'
bottles( n ) = number( n ) + ' bottles'
 
verse( 0 ) = ('No more bottles of beer on the wall, no more bottles of beer.\n'
+ 'Go to the store and buy some more, ninety-nine bottles of beer on the wall.')
verse( n ) = (cap( bottles(n) ) + ' of beer on the wall, ' + bottles( n ) + ' of beer.\n'
+ 'Take one down and pass it around, ' + bottles( n-1 )
+ ' of beer on the wall.\n')
 
for i <- 99..0 by -1 do println( verse(i) )

[edit] GAP

Bottles := function(n)
local line, i, j, u;
line := function(n)
s := String(n);
if n < 2 then
return Concatenation(String(n), " bottle of beer");
else
return Concatenation(String(n), " bottles of beer");
fi;
end;
for i in [1 .. n] do
j := n - i + 1;
u := line(j);
Display(Concatenation(u, " on the wall"));
Display(u);
Display("Take one down, pass it around");
Display(Concatenation(line(j - 1), " on the wall"));
if i <> n then
Display("");
fi;
od;
end;

[edit] gnuplot

if (!exists("bottles")) bottles = 99
print sprintf("%i bottles of beer on the wall", bottles)
print sprintf("%i bottles of beer", bottles)
print "Take one down, pass it around"
bottles = bottles - 1
print sprintf("%i bottles of beer on the wall", bottles)
print ""
if (bottles > 0) reread

[edit] Go

[edit] No sense of humor

package main
 
import "fmt"
 
func main() {
cardinality := func (i int) string {
if i!=1 {
return "s"
}
return ""
}
for i := 99; i > 0; i-- {
fmt.Printf("%d bottle%s of beer on the wall\n", i, cardinality(i))
fmt.Printf("%d bottle%s of beer\n", i, cardinality(i))
fmt.Printf("Take one down, pass it around\n")
fmt.Printf("%d bottle%s of beer on the wall\n", i-1, cardinality(i-1))
}
}

[edit] Typoglycemic

With code from RC tasks Number names, Knuth shuffle.

package main
 
import (
"fmt"
"math/rand"
"strings"
"time"
)
 
func main() {
rand.Seed(time.Now().UnixNano())
for i := 99; i > 0; i-- {
fmt.Printf("%s %s %s\n",
slur(numberName(i), i),
pluralizeFirst(slur("bottle of", i), i),
slur("beer on the wall", i))
fmt.Printf("%s %s %s\n",
slur(numberName(i), i),
pluralizeFirst(slur("bottle of", i), i),
slur("beer", i))
fmt.Printf("%s %s %s\n",
slur("take one", i),
slur("down", i),
slur("pass it around", i))
fmt.Printf("%s %s %s\n",
slur(numberName(i-1), i),
pluralizeFirst(slur("bottle of", i), i-1),
slur("beer on the wall", i))
}
}
 
// adapted from Number names task
func numberName(n int) string {
switch {
case n < 0:
case n < 20:
return small[n]
case n < 100:
t := tens[n/10]
s := n % 10
if s > 0 {
t += " " + small[s]
}
return t
}
return ""
}
 
var small = []string{"no", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
var tens = []string{"ones", "ten", "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"}
 
// pluralize first word of s by adding an s, but only if n is not 1.
func pluralizeFirst(s string, n int) string {
if n == 1 {
return s
}
w := strings.Fields(s)
w[0] += "s"
return strings.Join(w, " ")
}
 
// p is string to slur, d is drunkenness, from 0 to 99
func slur(p string, d int) string {
// shuffle only interior letters
a := []byte(p[1 : len(p)-1])
// adapted from Knuth shuffle task.
// shuffle letters with probability d/100.
for i := len(a) - 1; i >= 1; i-- {
if rand.Intn(100) >= d {
j := rand.Intn(i + 1)
a[i], a[j] = a[j], a[i]
}
}
// condense spaces
w := strings.Fields(p[:1] + string(a) + p[len(p)-1:])
return strings.Join(w, " ")
}
Output:

Things start out pretty well...

ninety nine bottles of beer on the wall
ninety nine bottles of beer
take one down pass it around
ninety eight bottles of beer on the wall
ninety eight bottles of beer on the wall
ninety eight bottles of beer
take one down pass it around
ninety seven bottles of beer on the wall
ninety seven boetlts of beer on the wall
ninety seven bottles of beer
take one down pass it around
ninety six botelts of beer on the wall

Soon,

eighty four bottles of bere wn the oall
ehigty four bottles of beer
tkae one down pnssti arouad
eihhty tgree bttoles of beer en tho wall
eighty three blottes of beet on rhe wall
eighty three bottles of beer
taen oke down pass it around
eiwyth tgo bttoles of beew on lhr eatl

It ends very well, if you're drinking along.

two btloots ef bre enehta wo ll
two bs tleootf beer
tnoeka e dwon pts ou nsaaird
one bolote tf betwr le ao enhl
one beoo ttlf blwtenr ehoa el
one bltooe tf beer
tne okae down pasaostiu rnd
no bletts oof beloethw r ea nl

[edit] Go!

Copied from The 99 Bottles of Beer web site with a minor bug fix.

-- 
-- 99 Bottles of Beer in Go!
-- John Knottenbelt
--
-- Go! is a multi-paradigm programming language that is oriented
-- to the needs of programming secure, production quality, agent
-- based applications.
--
-- http://www.doc.ic.ac.uk/~klc/dalt03.html
--
 
main .. {
include "sys:go/io.gof".
include "sys:go/stdlib.gof".
 
main() ->
drink(99);
stdout.outLine("Time to buy some more beer...").
 
drink(0) -> {}.
drink(i) -> stdout.outLine(
bottles(i) <> " on the wall,\n" <>
bottles(i) <> ".\n" <>
"take one down, pass it around,\n" <>
bottles(i-1) <> " on the wall.\n");
drink(i-1).
 
bottles(0) => "no bottles of beer".
bottles(1) => "1 bottle of beer".
bottles(i) => i^0 <> " bottles of beer".
}

[edit] Gosu

 
for (i in 99..0) {
 
print("${i} bottles of beer on the wall")
 
if (i > 0) {
print("${i} bottles of beer")
print("Take one down, pass it around")
}
print("");
 
}
 

[edit] Golfscript

[296,{3/)}%-1%["No more"]+[" bottles":b]294*[b-1<]2*+[b]+[" of beer on the wall\n".8<"\nTake one down, pass it around\n"+1$n+]99*]zip

[edit] Groovy

[edit] Basic Solution

With a closure to handle special cardinalities of bottles.

def bottles = { "${it==0 ? 'No more' : it} bottle${it==1 ? '' : 's' }" }
 
99.downto(1) { i ->
print """
${bottles(i)} of beer on the wall
${bottles(i)} of beer
Take one down, pass it around
${bottles(i-1)} of beer on the wall
"""

}

[edit] Single Print Version

Uses a single print algorithm for all four lines. Handles cardinality on bottles, uses 'No more' instead of 0.

298.downto(2) {
def (m,d) = [it%3,(int)it/3]
print "${m==1?'\n':''}${d?:'No more'} bottle${d!=1?'s':''} of beer" +
"${m?' on the wall':'\nTake one down, pass it around'}\n"
}

[edit] Bottomless Beer Solution

Using more closures to create a richer lyrical experience.

def bottles = { "${it==0 ? 'No more' : it} bottle${it==1 ? '' : 's' }" }
 
def initialState = {
"""${result(it)}
${resultShort(it)}"""

}
 
def act = {
it > 0 ?
"Take ${it==1 ? 'it' : 'one'} down, pass it around" :
"Go to the store, buy some more"
}
 
def delta = { it > 0 ? -1 : 99 }
 
def resultShort = { "${bottles(it)} of beer" }
 
def result = { "${resultShort(it)} on the wall" }
 
// //// uncomment commented lines to create endless drunken binge //// //
// while (true) {
99.downto(0) { i ->
print """
${initialState(i)}
${act(i)}
${result(i+delta(i))}
"""

}
// Thread.sleep(1000)
// }

[edit] GUISS

We will just use the calculator and keep taking one off. We do not get the full text here, but the number of the calculator shows how many bottles we still have left to drink:

Start,Programs,Accessories,Calculator,Button:9,Button:9,
Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals],
Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals],
Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals],
Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals]
 

We haven't drank all of the bottles at this point, but we can keep going, if we want.

[edit] Haskell

A relatively concise solution:

main = mapM_ (putStrLn . beer) [99, 98 .. 0]
beer 1 = "1 bottle of beer on the wall\n1 bottle of beer\nTake one down, pass it around"
beer 0 = "better go to the store and buy some more."
beer v = show v ++ " bottles of beer on the wall\n"
++ show v
++" bottles of beer\nTake one down, pass it around\n"
++ head (lines $ beer $ v-1) ++ "\n"

As a list comprehension:

import qualified Char
 
main = putStr $ concat
[up (bob n) ++ wall ++ ", " ++ bob n ++ ".\n" ++
pass n ++ bob (n - 1) ++ wall ++ ".\n\n" |
n <- [99, 98 .. 0]]
where bob n = (num n) ++ " bottle" ++ (s n) ++ " of beer"
wall = " on the wall"
pass 0 = "Go to the store and buy some more, "
pass _ = "Take one down and pass it around, "
up (x : xs) = Char.toUpper x : xs
num (-1) = "99"
num 0 = "no more"
num n = show n
s 1 = ""
s _ = "s"

Another version, which uses a Writer monad to collect each part of the song. It also uses Template Haskell to generate the song at compile time.

{-# LANGUAGE TemplateHaskell #-}
-- build with "ghc --make beer.hs"
module Main where
import Language.Haskell.TH
import Control.Monad.Writer
 
-- This is calculated at compile time, and is equivalent to
-- songString = "99 bottles of beer on the wall\n99 bottles..."
songString =
$(let
sing = tell -- we can't sing very well...
 
someBottles 1 = "1 bottle of beer "
someBottles n = show n ++ " bottles of beer "
 
bottlesOfBeer n = (someBottles n ++)
 
verse n = do
sing $ n `bottlesOfBeer` "on the wall\n"
sing $ n `bottlesOfBeer` "\n"
sing $ "Take one down, pass it around\n"
sing $ (n - 1) `bottlesOfBeer` "on the wall\n\n"
 
song = execWriter $ mapM_ verse [99,98..1]
 
in return $ LitE $ StringL $ song)
 
main = putStr songString

[edit] Haxe

[edit] Simple solution

class RosettaDemo
{
static public function main()
{
singBottlesOfBeer(100);
}
 
static function singBottlesOfBeer(bottles : Int)
{
var plural : String = 's';
 
while (bottles >= 1)
{
Sys.println(bottles + " bottle" + plural + " of beer on the wall,");
Sys.println(bottles + " bottle" + plural + " of beer!");
Sys.println("Take one down, pass it around,");
if (bottles - 1 == 1)
{
plural = '';
}
 
if (bottles > 1)
{
Sys.println(bottles-1 + " bottle" + plural + " of beer on the wall!\n");
}
else
{
Sys.println("No more bottles of beer on the wall!");
}
bottles--;
}
}
}

[edit] Macro solution

All those counters, loops and conditinal blocks are pretty expensive in runtime compared to single print of fully inlined text of the song. Let's generate that print with macro.

class Bottles {
 
static public function main () : Void {
singBottlesOfBeer(100);
}
 
 
macro static public function singBottlesOfBeer (bottles:Int) {
var lines = [];
var s : String = 's';
 
var song : String = '';
while( bottles >= 1 ){
song += '$bottles bottle$s of beer on the wall,\n';
song += '$bottles bottle$s of beer!\n';
song += 'Take one down, pass it around,\n';
 
bottles --;
 
if( bottles > 1 ){
song += '$bottles bottles of beer on the wall!\n\n';
}else if( bottles == 1 ){
s = '';
song += '$bottles bottle of beer on the wall!\n\n';
}else{
song += 'No more bottles of beer on the wall!\n';
}
}
 
return macro Sys.print($v{song});
}
 
}

[edit] HicEst

DO x = 99, 1, -1
WRITE() x , "bottles of beer on the wall"
BEEP("T16 be be be bH bH bH be be be 2be ")
 
WRITE() x , "bottles of beer"
BEEP("2p f f f c c c 2f ")
 
WRITE() "take one down, pass it around"
BEEP("2p 2d d d 2p d d d 2d ")
 
WRITE() x , "bottles of beer on the wall"
BEEP("2p #A #A #A c c d #d #d #d 2#d 2p")
ENDDO

[edit] HQ9+

See 99 Bottles of Beer/EsoLang

[edit] Icon and Unicon

The default is 99 bottles, but you can change this on the command line for really long trips...

procedure main(args)
numBeers := integer(args[1]) | 99
drinkUp(numBeers)
end
 
procedure drinkUp(beerMax)
static beerMap
initial {
beerMap := table(" bottles")
beerMap[1] := " bottle"
}
 
every beerCount := beerMax to 1 by -1 do {
writes( beerCount,beerMap[beerCount]," of beer on the wall, ")
write( beerCount,beerMap[beerCount]," of beer.")
 
writes("Take one down and pass it around, ")
write(case x := beerCount-1 of {
0 : "no more bottles"
default : x||beerMap[x]
}," of beer on the wall.\n")
}
 
write("No more bottles of beer on the wall, no more bottles of beer.")
write("Go to the store and buy some more, ",
beerMax," bottles of beer on the wall.")
end

[edit] IDL

Pro bottles
 
for i=1,99 do begin
print, 100-i, " bottles of beer on the wall.", 100-i, $
" bottles of beer.", " Take one down, pass it around," , $
99-i, " bottles of beer on the wall."
endfor
End
 
 

Since in IDL "FOR"-loops are the embodiment of pure evil (see http://www.idlcoyote.com/tips/forloops.html and http://www.idlcoyote.com/tips/forloops2.html) there is also a loop free IDL way:

Pro bottles_noloop
b=(reverse(shift(sindgen(100),-1)))[1:99]
b2=reverse(sindgen(99))
wallT=replicate(' bottles of beer on the wall.', 100)
wallT2=replicate(' bottles of beer.', 100)
takeT=replicate('Take one down, pass it around,', 100)
print, b+wallT+string(10B)+b+wallT2+string(10B)+takeT+string(10B)+b2+wallT+string(10B)
End

[edit] Inform 6

[ Bottles i;
if(i == 1) return "bottle";
 
return "bottles";
];
 
[ Beer i;
print i, " ", (string) Bottles(i), " of beer on the wall^";
print i, " ", (string) Bottles(i), " of beer^";
print "Take one down, pass it around^";
i--;
print i, " ", (string) Bottles(i), " of beer on the wall^^";
 
if(i ~= 0) Beer(i);
];
 
[ Main;
Beer(99);
];
 

[edit] Inform 7

[edit] Programmatic solution

Beer Hall is a room.
 
When play begins:
repeat with iteration running from 1 to 99:
let N be 100 - iteration;
say "[N] bottle[s] of beer on the wall[line break]";
say "[N] bottle[s] of beer[line break]";
say "Take one down, pass it around[line break]";
say "[N - 1] bottle[s] of beer on the wall[paragraph break]";
end the story.

[edit] World model solution

This solution uses in-game objects to represent the wall and the bottles.

Beer Hall is a room.
 
The plural of bottle of beer is bottles of beer. A bottle of beer is a kind of thing.
 
The wall is a scenery supporter in Beer Hall. 99 bottles of beer are on the wall.
 
When play begins:
while something is on the wall:
say "[what's on the wall] on the wall[line break]";
say "[what's on the wall][line break]";
say "Take one down, pass it around[line break]";
remove a random thing on the wall from play;
say "[what's on the wall] on the wall[paragraph break]";
end the story.
 
To say what's on the wall:
if more than one thing is on the wall, say list of things on the wall;
otherwise say "[number of things on the wall in words] bottle[s] of beer".

[edit] Intercal

See 99 Bottles of Beer/EsoLang

[edit] Io

bottles := method(i,
if(i==0, return "no more bottles of beer")
if(i==1, return "1 bottle of beer")
"" .. i .. " bottles of beer"
)
for(i, 99, 1, -1,
write(
bottles(i), " on the wall, ",
bottles(i), ",\n",
"take one down, pass it around,\n",
bottles(i - 1), " on the wall.\n\n"
)
)

[edit] Ioke

bottle = method(i,
case(i,
0, "no more bottles of beer",
1, "1 bottle of beer",
"#{i} bottles of beer"))
 
(99..1) each(i,
"#{bottle(i)} on the wall, " println
"take one down, pass it around," println
"#{bottle(i - 1)} on the wall.\n" println
)

[edit] J

As posted at the J wiki

bob =: ": , ' bottle' , (1 = ]) }. 's of beer'"_
bobw=: bob , ' on the wall'"_
beer=: bobw , ', ' , bob , '; take one down and pass it around, ' , bobw@<:
beer"0 >:i.-99
Output:
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
...
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; take one down and pass it around, 0 bottles of beer on the wall 

[edit] Java

[edit] Console

MessageFormat's choice operator is used to properly format plurals.

import java.text.MessageFormat;
public class Beer
{
static String bottles(final int n)
{
return MessageFormat.format("{0,choice,0#No more bottles|1#One bottle|2#{0} bottles} of beer", n);
}
public static void main(final String[] args)
{
String byob = bottles(99);
for (int x = 99; x > 0;)
{
System.out.println(byob + " on the wall");
System.out.println(byob);
System.out.println("Take one down, pass it around");
byob = bottles(--x);
System.out.println(byob + " on the wall\n");
}
}
}

Optimized

public class Beer
{
public static void main(final String[] args)
{
int beer = 99;
StringBuilder sb = new StringBuilder();
String data[] = new String[] { " bottles of beer on the wall\n",
" bottles of beer.\nTake one down, pass it around,\n",
"Better go to the store and buy some more." };
 
while (beer > 0)
sb.append(beer).append(data[0]).append(beer).append(data[1]).append(--beer).append(data[0]).append("\n");
 
System.out.println(sb.append(data[2]).toString());
}
}

Recursive

public class Beer
{
public static void main(String args[])
{
song(99);
}
 
public static void song(int b)
{
if(b>=0)
{
if(b>1)
System.out.println(b+" bottles of beer on the wall\n"+b+" bottles of beer\nTake one down, pass it around\n"+(b-1)+" bottles of beer on the wall.\n");
else if(b==1)
System.out.println(b+" bottle of beer on the wall\n"+b+" bottle of beer\nTake one down, pass it around\n"+(b-1)+" bottles of beer on the wall.\n");
else
System.out.println(b+" bottles of beer on the wall\n"+b+" bottles of beer\nBetter go to the store and buy some more!");
song(b-1);
}
}
}

[edit] An object-oriented solution

Translation of: C++

See: 99 Bottles of Beer/Java/Object Oriented

[edit] GUI

Library: Swing
Library: AWT

This version requires user interaction. The first two lines are shown in a text area on a window. The third line is shown on a button which you need to click to see the fourth line in a message box. The numbers update and the process repeats until "0 bottles of beer on the wall" is shown in a message box, when the program ends.

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
public class Beer extends JFrame implements ActionListener{
private int x;
private JButton take;
private JTextArea text;
public static void main(String[] args){
new Beer();//build and show the GUI
}
 
public Beer(){
x= 99;
take= new JButton("Take one down, pass it around");
text= new JTextArea(4,30);//size the area to 4 lines, 30 chars each
text.setText(x + " bottles of beer on the wall\n" + x + " bottles of beer");
text.setEditable(false);//so they can't change the text after it's displayed
take.addActionListener(this);//listen to the button
setLayout(new BorderLayout());//handle placement of components
add(text, BorderLayout.CENTER);//put the text area in the largest section
add(take, BorderLayout.SOUTH);//put the button underneath it
pack();//auto-size the window
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//exit on "X" (I hate System.exit...)
setVisible(true);//show it
}
 
public void actionPerformed(ActionEvent arg0){
if(arg0.getSource() == take){//if they clicked the button
JOptionPane.showMessageDialog(null, --x + " bottles of beer on the wall");//show a popup message
text.setText(x + " bottles of beer on the wall\n" + x + " bottles of beer");//change the text
}
if(x == 0){//if it's the end
dispose();//end
}
}
}

[edit] JavaScript

[edit] ES3-5

var beer = 99;
while (beer > 0) {
var verse = [
beer + " bottles of beer on the wall,",
beer + " bottles of beer!",
"Take one down, pass it around",
(beer - 1) + " bottles of beer on the wall!"
].join("\n");
 
console.log(verse);
 
beer--;
}
 

[edit] ES6

let beer = 99;
while (beer > 0) {
let verse = `${beer} bottles of beer on the wall,
${beer} bottles of beer!
Take one down, pass it around
${beer-1} bottles of beer on the wall`;
 
console.log(verse);
beer--;
}

[edit] Other Examples

More skilled solution "one-liner" with grammar check

// Line breaks are in HTML
var beer; while ((beer = typeof beer === "undefined" ? 99 : beer) > 0) document.write( beer + " bottle" + (beer != 1 ? "s" : "") + " of beer on the wall<br>" + beer + " bottle" + (beer != 1 ? "s" : "") + " of beer<br>Take one down, pass it around<br>" + (--beer) + " bottle" + (beer != 1 ? "s" : "") + " of beer on the wall<br>" );

Object Oriented

function Bottles(count) {
this.count = count || 99;
}
 
Bottles.prototype.take = function() {
var verse = [
this.count + " bottles of beer on the wall,",
this.count + " bottles of beer!",
"Take one down, pass it around",
(this.count - 1) + " bottles of beer on the wall!"
].join("\n");
 
console.log(verse);
 
this.count--;
};
 
Bottles.prototype.sing = function() {
while (this.count) {
this.take();
}
};
 
var bar = new Bottles(99);
bar.sing();

An alternative version:

function bottleSong(n) {
if (!isFinite(Number(n)) || n == 0) n = 100;
var a = '%% bottles of beer',
b = ' on the wall',
c = 'Take one down, pass it around',
r = '<br>'
p = document.createElement('p'),
s = [],
re = /%%/g;
 
while(n) {
s.push((a+b+r+a+r+c+r).replace(re, n) + (a+b).replace(re, --n));
}
p.innerHTML = s.join(r+r);
document.body.appendChild(p);
}
 
window.onload = bottleSong;

[edit] Joy

LIBRA
 
_beerlib == true ;
 
HIDE
beer == "of beer " putchars ;
wall == "on the wall" putchars ;
take1 == "Take one down and pass it around, " putchars ;
dup3 == dup dup dup ;
comma == ", " putchars ;
period == '. putch ;
bottles == [dup small]
[ [null] [pop "no more bottles " putchars] [put "bottle " putchars] ifte]
[put "bottles " putchars] ifte ;
sing-verse == dup3 bottles beer wall comma
bottles beer ".\n" putchars
take1 1 - bottles beer wall period newline newline ;
sing-verse-0 == "No more bottles of beer on the wall, no more bottles of beer\n" putchars
"Go to the store and buy some more, " putchars
99 bottles pop beer wall period newline ;
 
IN
(* n -- *)
sing-verses == [null]
[sing-verse-0]
[sing-verse 1 -] tailrec .

[edit] Julia

one-liner

for i = 99:-1:1 print("\n$i bottles of beer on the wall\n$i bottles of beer\nTake one down, pass it around\n$(i-1) bottles of beer on the wall\n") end

another solution, handling grammar cases "No more bottles", "1 bottle", "<n> bottles"

bottles(n) = n==0 ? "No more bottles" :
n==1 ? "1 bottle" :
"$n bottles"
 
for n = 99:-1:1
println("""
$(bottles(n)) of beer on the wall
$(bottles(n)) of beer
Take one down, pass it around
$(bottles(n-1)) of beer on the wall
""")
end

shorter, but more criptic, version of the previous `bottles` function

bottles(n) = "$(n==0 ? "No more" : n) bottle$(n==1 ? "" : "s")"

[edit] K

`0:\:{x[z],y,a,x[z],a,"Take one down, pass it around",a,x[z-1],y,a,a:"\n"}[{($x)," bottle",:[x=1;"";"s"]," of beer"};" on the wall"]'|1_!100

[edit] Kotlin

fun main(args : Array<String>) {
var i = 99
while (i > 0) {
 
System.out?.println("${i} bottles of beer on the wall")
System.out?.println("${i} bottles of beer")
System.out?.println("Take one down, pass it around")
i--;
}
System.out?.println("0 bottles of beer on the wall")
}
 

[edit] LabVIEW

See 99 Bottles of Beer/VPL

[edit] Lasso

[edit] Simple loop

local(
beer = 99,
song = ''
)
while(#beer > 0) => {
#song->append(
#beer + ' bottles of beer on the wall\n' +
#beer + ' bottles of beer\n' +
'Take one down, pass it around\n' +
(#beer-1) + ' bottles of beer on the wall\n\n'
)
#beer--
}
 
#song

[edit] Query Expression

(with beer in 99 to 1 by -1 select
#beer + ' bottles of beer on the wall' +
#beer + ' bottles of beer\n' +
'Take one down, pass it around\n' +
--#beer + ' bottles of beer on the wall\n'
)->join('\n')


[edit] Query Expression with Autocollect

// this example adds an "s" to bottle until there is only 1 bottle left on the wall
 
local(s = 's')
with n in 99 to 1 by -1 do {^
#n + ' bottle' + #s + ' of beer on the wall,<br>'
#n + ' bottle' + #s + ' of beer,<br>'
#n = #n - 1
#s = (#n != 1 ? 's' | '')
'Take one down, pass it around,<br>'
#n + ' bottle' + #s + ' of beer on the wall.<br><br>'
^}

[edit] LaTeX

[edit] Recursive

\documentclass{article}
 
\newcounter{beer}
 
\newcommand{\verses}[1]{
\setcounter{beer}{#1}
\par\noindent
\arabic{beer} bottles of beer on the wall,\\
\arabic{beer} bottles of beer!\\
Take one down, pass it around---\\
\addtocounter{beer}{-1}
\arabic{beer} bottles of beer on the wall!\\
\ifnum#1>0
\verses{\value{beer}}
\fi
}
 
\begin{document}
\verses{99}
\end{document
}

[edit] Iterative

The \loop macro is tail-recursive (Knuth 1984, page 219). Just for fun, this version uses Roman numerals.

\documentclass{article}
 
\newcounter{beer}
\newcounter{showC}
 
\newcommand{\verses}[1]{
\setcounter{beer}{#1}
\loop
\par\noindent
\Roman{beer} bottles of beer on the wall,\\
\Roman{beer} bottles of beer!\\
Take one down, pass it around---\\
\addtocounter{beer}{-1
}
% Romans didn't know how to write zero ;-)
\ifnum\value{beer}=0 ZERO \else\Roman{beer} \fi
bottles of beer on the wall!\\
\ifnum\value{beer}>0
\repeat
}
 
\begin{document}
\verses{99}
\end{document
}

[edit] References

  • Knuth, Donald E. (1984). The TeXbook, Addison Wesley.

[edit] lang5

: ~ 2 compress "" join ;
: verses(*)
dup " bottles of beer on the wall\n" ~ .
dup " bottles of beer\n" ~ .
"Take one down, pass it around\n" .
1 - " bottles of beer on the wall\n\n" ~ .
 ;
 
99 iota 1 + reverse verses

[edit] Lhogho

to bottle :i
if :i = 0 [output "|No more bottles of beer|]
if :i = 1 [output "|One bottle of beer|]
output word :i "| bottles of beer|
end
 
to it_one :n
if :n = 1 [output "it][output "one]
end
 
to verse :i
(print bottle :i "| on the wall,|)
(print word bottle :i ".)
(print "Take it_one :i "|down, pass it round|)
(print bottle :i - 1 "| on the wall.|)
print
end
 
to sing :i
if :i = 0
[
print "|No more bottles of beer on the wall,
No more bottles of beer.
Go to the store and buy some more.
99 bottles of beer on the wall.|
stop
]
verse :i
sing :i - 1
end
 
;Using it:
sing 99

[edit] LiveCode

function beerMe numberOfBottles
   put "XX bottles of beer on the wall" into verseA
   put "Take one down, pass it around" into verseB
   repeat with N = numberOfBottles down to 1
      put replaceText(verseA,"XX",N) & cr & word 1 to 4 of \
replaceText(verseA,"XX",N) & cr & verseB & cr & replaceText(verseA,"XX",N-1) \
& cr & cr after theSong
   end repeat
   return theSong
end beerMe

[edit] Lisp

See 99 Bottles of Beer/Lisp

[edit] LLVM

See 99 Bottles of Beer/Assembly

[edit]

to bottles :n
if :n = 0 [output [No more bottles]]
if :n = 1 [output [1 bottle]]
output sentence :n "bottles
end
to verse :n
print sentence bottles :n [of beer on the wall]
print sentence bottles :n [of beer]
print [Take one down, pass it around]
print sentence bottles :n-1 [of beer on the wall]
end
for [n 99 1] [verse :n (print)]

[edit] Logtalk

:- object(bottles).
 
:- initialization(sing(99)).
 
sing(0) :-
write('No more bottles of beer on the wall, no more bottles of beer.'), nl,
write('Go to the store and buy some more, 99 bottles of beer on the wall.'), nl, nl.
sing(N) :-
N > 0,
N2 is N -1,
beers(N), write(' of beer on the wall, '), beers(N), write(' of beer.'), nl,
write('Take one down and pass it around, '), beers(N2), write(' of beer on the wall.'), nl, nl,
sing(N2).
 
beers(0) :-
write('no more bottles').
beers(1) :-
write('1 bottle').
beers(N) :-
N > 1,
write(N), write(' bottles').
 
:- end_object.

[edit] LOLCODE

See 99 Bottles of Beer/EsoLang

[edit] Lua

local bottles = 99
 
local function plural (bottles) if bottles == 1 then return '' end return 's' end
while bottles > 0 do
print (bottles..' bottle'..plural(bottles)..' of beer on the wall')
print (bottles..' bottle'..plural(bottles)..' of beer')
print ('Take one down, pass it around')
bottles = bottles - 1
print (bottles..' bottle'..plural(bottles)..' of beer on the wall')
print ()
end

With a numeric for-loop and string formatting:

verse = [[%i bottle%s of beer on the wall
%i bottle%s of beer
Take one down, pass it around
%i bottle%s of beer on the wall
]]
function suffix(i) return i ~= 1 and 's' or '' end
 
for i = 99, 1, -1 do
print(verse:format(i, suffix(i), i, suffix(i), i-1, suffix(i-1)))
end

[edit] Lucid

// Run luval with -s inside the lucid shell script
// The print out is a list of lines. So the output is not separated by new lines, rather
// by '[' and ']' -- I cant figure out how to do string concatenation with numbers in lucid.
// beer(N) ^ bottle(N) ^ wall ^ beer(N) ^ bottle(N) ^ pass ^ beer(N-1) ^ bottle(N-1) ^ wall
// should have worked but doesn't
[%beer(N),bottle(N),wall,beer(N),bottle(N),pass,beer(N-1),bottle(N-1),wall%]
where
N = 100 fby N - 1;
wall = if N > 0 then ` On the wall ' else eod fi;
pass = `Take one down and pass it around.';
beer(A) = if A > 0 then A else `No more' fi;
bottle(A) = if A eq 1 then `bottle of beer' else `bottles of beer' fi;
end

[edit] M4

define(`BOTTLES', `bottles of beer')dnl
define(`BOTTLE', `bottle of beer')dnl
define(`WALL', `on the wall')dnl
define(`TAKE', `take one down, pass it around')dnl
define(`NINETEEN', `$1 ifelse(`$1',`1',BOTTLE,BOTTLES) WALL
$1 ifelse(`$1',`1',BOTTLE,BOTTLES)
ifelse(`$1',`0',,`TAKE')
ifelse(`$1',`0',,`NINETEEN(eval($1-1))')')dnl
NINETEEN(99)

[edit] make

[edit] BSD make

Library: jot
Works with: BSD make
START = 99
UP != jot - 2 `expr $(START) - 1` 1
 
0-bottles-of-beer: 1-bottle-of-beer
@echo No more bottles of beer on the wall!
 
1-bottle-of-beer: 2-bottles-of-beer
@echo One last bottle of beer on the wall!
@echo
@echo One last bottle of beer on the wall,
@echo One last bottle of beer,
@echo Take it down, pass it around.
 
.for COUNT in $(UP)
ONE_MORE != expr 1 + $(COUNT)
$(COUNT)-bottles-of-beer: $(ONE_MORE)-bottles-of-beer
@echo $(COUNT) bottles of beer on the wall!
@echo
@echo $(COUNT) bottles of beer on the wall,
@echo $(COUNT) bottles of beer,
@echo Take one down, pass it around.
.endfor
 
$(START)-bottles-of-beer:
@echo $(START) bottles of beer on the wall,
@echo $(START) bottles of beer.
@echo Take one down, pass it around.

Usage: make or make START=99

[edit] GNU make

Works with: GNU make version 3.81
PRED=`expr $* - 1`
 
1-bottles: 1-beer pass
@echo "No more bottles of beer on the wall"
 
%-bottles: %-beer pass
@echo "$(PRED) bottles of beer on the wall\n"
@-$(MAKE) $(PRED)-bottles
 
1-beer:
@echo "One bottle of beer on the wall, One bottle of beer"
 
%-beer:
@echo "$* bottles of beer on the wall, $* bottles of beer"
 
pass:
@echo "Take one down and pass it around,"

Usage: make 99-bottles

This will fork 99 make processes. You might need to raise your process limit (ulimit -p).

[edit] GNU make

[edit] Without using a shell command to decrement the counter
Works with: GNU make version 3.81
digits:=9 8 7 6 5 4 3 2 1 0
numbers:=$(foreach x,$(filter-out 0,$(digits)),$(foreach y,$(digits),$x$y))
numbers+=$(digits)
 
bottles=bottle$(if $(findstring /1/,$@),,s)
num=$(if $(findstring /0/,$@),$(empty),$(@F))
action=$(if $(findstring /0/,$@),$(buy),$(pass))
 
beer:=of beer
wall:=on the wall
empty:=No more
pass:=Take one down and pass it around.
buy:=Go to the store and buy some more.
 
# Function to generate targets for each verse of the song.
define verse
.PHONY: $1
$1: verse/$1/$1 prelude/$2/$2 $2
 
.PHONY: $1-bottles
$1-bottles: $1
 
most?=$1
endef
 
# Recursive function that loops through the 100 numbers.
define verses
$$(eval $$(call verse,$$(word 1,$1),$$(word 2,$1)))
$$(if $$(word 2,$1),$$(eval $$(call verses,$$(filter-out $$(word 1,$1),$1))))
endef
 
# Generate the targets for the 100 numbers.
$(eval $(call verses,$(numbers)))
 
 
# Main lines in the verse.
.PHONY: verse/%
verse/%:
@echo "$(num) $(bottles) $(beer) $(wall)."
@echo "$(num) $(bottles) $(beer)."
@echo "$(action)"
 
# Last line of a verse, which is a prelude to the next verse.
.PHONY: prelude/%
prelude/%:
@echo "$(num) $(bottles) $(beer) $(wall)."
@echo ""
 
# Special target for the last line of the song.
.PHONY: prelude/
prelude/:
@echo "$(most) $(bottles) $(beer) $(wall)!"
@echo ""
 

Usage: make or make N-bottles or make N

A version of this script with more comments and an automated test can be found on github.com.

[edit] Mathematica

Bottle[n_] := ToString[n] <> If[n==1," bottle"," bottles"] <> " of beer"
 
BottleSong[n_] := Speak[
Bottle[n] <> " on the wall," <>
Bottle[n] <>
", take one down, pass it around," <>
Bottle[n-1] <> " on the wall."
]
 
BottleSong /@ Range[99,1,-1]

[edit] MATLAB

function ninetyNineBottlesOfBeer()
 
disp( [ sprintf(['%d bottles of beer on the wall, %d bottles of beer.\n'...
'Take one down, pass it around...\n'],[(99:-1:2);(99:-1:2)])...
sprintf(['1 bottle of beer on the wall, 1 bottle of beer.\nTake'...
'one down, pass it around;\nNo more bottles of beer on the wall.']) ] );
 
%The end of this song makes me sad. The shelf should always have more
%beer...like college.
 
end

[edit] Maxima

bottles(n) := for i from n thru 1 step -1 do (
printf(true, "~d bottle~p of beer on the wall~%", i, i),
printf(true, "~d bottle~p of beer~%", i, i),
printf(true, "Take one down, pass it around~%"),
printf(true, "~d bottle~p of beer on the wall~%", i - 1, i - 1),
disp(""))$
 
bottles(3);
/*
 
3 bottles of beer on the wall
3 bottles of beer
Take one down, pass it around
2 bottles of beer on the wall
 
2 bottles of beer on the wall
2 bottles of beer
Take one down, pass it around
1 bottle of beer on the wall
 
1 bottle of beer on the wall
1 bottle of beer
Take one down, pass it around
0 bottles of beer on the wall
 
*/

[edit] MAXScript

escapeEnable  = true 
resetMaxFile #noPrompt
viewport.setType #view_top
max tool maximize
viewport.SetRenderLevel #smoothhighlights
delay = 1.6
a = text size:30
a.wirecolor = white
theMod = extrude()
addModifier a theMod
 
for i in 99 to 1 by -1 do -- this will iterate through 99 times use the escape key to terminate.
(
a.text = (i as string + " bottles of beer on the wall")
redrawViews()
sleep delay
a.text = (i as string + " bottles of beer")
redrawViews()
sleep delay
a.text = "Take one down, pass it around"
redrawViews()
sleep delay
a.text = ((i-1) as string + " bottles of beer on the wall")
redrawViews()
sleep delay
)

[edit] A one-line version

Since MAXscript is an expression based language (everything returns a value), it is relatively easy to write long expressions that are only one line long. the following single-line snippet (broken for clarity on the webpage) produces a grammatically correct printout of the song.

for i = 99 to 1 by -1 do (print (i as string + (if i == 1 then " bottle" else " bottles") + " of beer on the wall\n" + i as string +\ 
(if i == 1 then " bottle" else " bottles") + " of beer\nTake one down, pass it around\n" + (i - 1) as string + (if i - 1 == 1 then "\
bottle" else " bottles") + " of beer on the wall\n" + (if i - 1 == 0 then "\nno more beer" else "")))

[edit] Mirah

plural = 's'
99.downto(1) do |i|
puts "#{i} bottle#{plural} of beer on the wall,"
puts "#{i} bottle#{plural} of beer"
puts "Take one down, pass it around!"
plural = '' if i - 1 == 1
if i > 1
puts "#{i-1} bottle#{plural} of beer on the wall!"
puts
else
puts "No more bottles of beer on the wall!"
end
end
 

[edit] mIRC Scripting Language

var %x = 99
while (%x) {
echo -ag %x bottles of beer on the wall
echo -ag %x bottles of beer
echo -ag Take one down, pass it around
dec %x
echo -ag %x bottles of beer on the wall
}

[edit] mLite

val NL = implode [#"newline"]
 
fun itone 1 = "it"
| n = "one"
 
fun plural (s, 0) = ("no " @ s @ "s")
| (s, 1) = ("1 " @ s)
| (s, n) = (ntos n @ " " @ s @ "s")
 
fun verse 0 = "no bottles of beer on the wall" @ NL @
"no bottles of beer" @ NL @
"go to the store and buy some more" @ NL @
"99 bottles of beer on the wall" @ NL @ NL
| x = plural ("bottle",x) @ " of beer on the wall" @ NL @
plural ("bottle",x) @ " of beer" @ NL @
"take " @ (itone x) @ " down and pass it round" @ NL @
plural ("bottle", (x-1)) @ " of beer on the wall" @ NL @ NL
 
fun bottles x = map (print o verse) (rev (0 :: iota (1, x)))
 
fun default (false, y) = y | (x, _) = x
 
;
bottles ` ston ` default (argv 0, "99")

Allows for number of bottles to be specified on command line with the default being 99, viz

mlite -f 99bob.m 2

Which, having specified 2 bottles, gives

2 bottles of beer on the wall
2 bottles of beer
take one down and pass it round
1 bottle of beer on the wall

1 bottle of beer on the wall
1 bottle of beer
take it down and pass it round
no bottles of beer on the wall

no bottles of beer on the wall
no bottles of beer
go to the store and buy some more
99 bottles of beer on the wall

[edit] ML/I

[edit] Simple iterative version

MCSKIP "WITH" NL
"" 99 bottles - simple iterative version
MCSKIP MT,<>
MCINS %.
"" Macro to generate singular or plural bottle(s)
MCDEF BOT WITHS () AS <bottle<>MCGO L0 IF %A1. EN 1
s>
"" Main macro - argument is initial number of bottles
MCDEF BOTTLES NL AS <MCSET T1=%A1.
%L1.%T1. BOT(%T1.) of beer on the wall
%T1. BOT(%T1.) of beer
Take one down, pass it around
MCSET T1=T1-1
%T1. BOT(%T1.) of beer on the wall
MCGO L0 IF T1 EN 0
 
MCGO L1
>
"" Do it
BOTTLES 99

[edit] Recursive version

MCSKIP "WITH" NL
"" 99 bottles - recursive version
MCSKIP MT,<>
MCINS %.
"" Macro to generate singular or plural bottle(s)
MCDEF BOT WITHS () AS <bottle<>MCGO L0 IF %A1. EN 1
s>
"" Main macro - recurses for each verse - argument is initial number of bottles
MCDEF BOTTLES NL AS <MCSET T1=%A1.
%T1. BOT(%T1.) of beer on the wall
%T1. BOT(%T1.) of beer
Take one down, pass it around
MCSET T1=T1-1
%T1. BOT(%T1.) of beer on the wall
MCGO L0 IF T1 EN 0
 
BOTTLES %T1.
>
"" Do it
BOTTLES 99


[edit] Macro Processing generalized version in 99 lines

This version demonstrates the macro text replacement capabilities central to ML/I.

The code defines a macro

Sing n containers of contents somewhere : deed ! replenish .

where the text (macro call)

Sing 99 bottles of beer on the wall: Take one down, pass it around ! Go to the store and buy some more .

is macro substituted with the specified 99 bottles of beer song. The text

Sing 7 bottles of Armagnac on the table: Take a swig, throw it down ! Emilie vists, she brings some more .

would be substituted with a shorter, more expensive, less social and sexier lyric.

Internal macros define English word replacements for decimal numbers from 0 to 99.

 
MCSKIP - WITH - NL
-- The line above defines the comment syntax: -- through to newline is completely deleted.
-- 99 Bottles of beer in 99 lines of ML/I by Parzival Herzog.
-- ML/I is P.J. Brown's famous general purpose macro processor designed in 1967.
--
-- Define nestable quotes {...}, replaced by the unevaluated text within:
MCSKIP MT, {}
-- Define non-nestable quotes "...", replaced by the unevaluated text within:
MCSKIP T, ""
-- Define the argument insertion and expression evaluation syntax:
-- ?e. is replaced by the value of macro expression e:
MCINS ?.
--
-- Top level macro: Sing N CONTAINERS of CONTENTS SOMEWHERE : DO THE DEED! REPLENISH.
MCDEF "Sing WITH SPACE SPACE of WITH SPACE SPACE  :  ! ." AS --
{MCDEF "CONTAINERS" AS "{"?A2."}"
MCDEF "CONTAINER" AS "{"MCSUB(CONTAINERS,1,-1)"}"
MCDEF "CONTENTS" AS "{"?A3."}"
MCDEF "SOMEWHERE" AS "{"?A4."}"
MCDEF "DO WITHS THE WITHS DEED" AS "{"?A5."}"
MCDEF "REPLENISH" AS "{"?A6."}"
MCSET T1 = ?A1.
MCDEF "n" AS "("?T1.")"
MCDEF "N" AS "{"n"}"
?L1.n of CONTENTS SOMEWHERE,
n of CONTENTS.
MCGO L2 UNLESS ?T1. GR 0
MCSET T1 = T1 - 1
MCDEF "n" AS "("?T1.")"
DO THE DEED:
n of CONTENTS SOMEWHERE.
 
MCGO L1
?L2.REPLENISH:
N of CONTENTS SOMEWHERE!}
--
-- (n): Wordify 0 to 99 CONTAINERS
MCDEF "()" AS {MCSET T1=?A1.
MCGO L1 UNLESS T1 GR 99
?T1. CONTAINERS-- Return the decimal number instead of words.
MCGO L0
?L1.MCGO L2 IF T1 GR 9
MCDEF "0units" AS ?T1."Unit"
MCGO L3
?L2.MCSET T3 = T1 - T1/10*10
MCDEF "0units" AS ?T3."unit"
MCSET T1 = T1 / 10
MCDEF "0tens" AS ?T1."Ten"
0tens?L3.0units CONTAINERS}
-- Exceptions:
MCDEF "(WITH 0 WITH)" AS {"No more" CONTAINERS}
MCDEF "(WITH 1 WITH)" AS {"One more" CONTAINER}
MCDEF "(WITH 11 WITH)" AS {"Eleven" CONTAINERS}
MCDEF "(WITH 12 WITH)" AS {"Twelve" CONTAINERS}
MCDEF "(WITH 13 WITH)" AS {"Thirteen" CONTAINERS}
MCDEF "(WITH 14 WITH)" AS {"Fourteen" CONTAINERS}
MCDEF "(WITH 15 WITH)" AS {"Fifteen" CONTAINERS}
MCDEF "(WITH 16 WITH)" AS {"Sixteen" CONTAINERS}
MCDEF "(WITH 17 WITH)" AS {"Seventeen" CONTAINERS}
MCDEF "(WITH 18 WITH)" AS {"Eighteen" CONTAINERS}
MCDEF "(WITH 19 WITH)" AS {"Nineteen" CONTAINERS}
-- Regular cases:
MCDEF "2Unit" AS {"Two"}
MCDEF "3Unit" AS {"Three"}
MCDEF "4Unit" AS {"Four"}
MCDEF "5Unit" AS {"Five"}
MCDEF "6Unit" AS {"Six"}
MCDEF "7Unit" AS {"Seven"}
MCDEF "8Unit" AS {"Eight"}
MCDEF "9Unit" AS {"Nine"}
MCDEF "0unit" AS
MCDEF "1unit" AS {" one"}
MCDEF "2unit" AS {" two"}
MCDEF "3unit" AS {" three"}
MCDEF "4unit" AS {" four"}
MCDEF "5unit" AS {" five"}
MCDEF "6unit" AS {" six"}
MCDEF "7unit" AS {" seven"}
MCDEF "8unit" AS {" eight"}
MCDEF "9unit" AS {" nine"}
MCDEF "1Ten" AS {"Ten"}
MCDEF "2Ten" AS {"Twenty"}
MCDEF "3Ten" AS {"Thirty"}
MCDEF "4Ten" AS {"Forty"}
MCDEF "5Ten" AS {"Fifty"}
MCDEF "6Ten" AS {"Sixty"}
MCDEF "7Ten" AS {"Seventy"}
MCDEF "8Ten" AS {"Eighty"}
MCDEF "9Ten" AS {"Ninety"}
--
-- The specified song:
Sing 99 bottles of beer on the wall: Take one down, pass it around! --
Go to the store and buy some more.
--
--
-- Try uncommenting the next two lines:
-- Sing 7 flasks of Armagnac on the table: Take a swig, throw it down!
-- Emilie vists, she brings some more.
 

[edit] Usage:

ml1 "Bottles of Beer.ml1"


[edit] Output:

 
Ninety nine bottles of beer on the wall,
Ninety nine bottles of beer.
Take one down, pass it around:
Ninety eight bottles of beer on the wall.
 
Ninety eight bottles of beer on the wall,
Ninety eight bottles of beer.
Take one down, pass it around:
Ninety seven bottles of beer on the wall.
 
...
 
 
One more bottle of beer on the wall,
One more bottle of beer.
Take one down, pass it around:
No more bottles of beer on the wall.
 
No more bottles of beer on the wall,
No more bottles of beer.
Go to the store and buy some more:
Ninety nine bottles of beer on the wall!
 
 

[edit] Modula-2

MODULE b99;
IMPORT InOut;
 
VAR nr : CARDINAL;
 
BEGIN
nr := 99;
REPEAT
InOut.WriteCard (nr, 4);
InOut.WriteString (" bottles of beer on the wall");
InOut.WriteLn;
InOut.WriteCard (nr, 4);
InOut.WriteString (" bottles of beer");
InOut.WriteLn;
InOut.WriteString ("Take one down, pass it around");
InOut.WriteLn;
DEC (nr);
InOut.WriteCard (nr, 4);
InOut.WriteString (" bottles of beer on the wall");
InOut.WriteLn;
InOut.WriteLn
UNTIL nr = 0
END b99.

[edit] Modula-3

MODULE Bottles EXPORTS Main;
 
IMPORT IO, Fmt;
 
BEGIN
FOR i := 99 TO 1 BY -1 DO
IO.Put(Fmt.Int(i) & " bottles of beer on the wall\n");
IO.Put(Fmt.Int(i) & " bottles of beer\n");
IO.Put("Take one down, pass it around\n");
IO.Put(Fmt.Int(i - 1) & " bottles of beer on the wall\n");
IO.Put("\n");
END;
END Bottles.

[edit] Monkey

Tic's every one and a half seconds and sings(text's) the song out.

 
 
Import mojo
 
Function Main ()
New NintyNineBottles
End
 
 
Class NintyNineBottles Extends App
 
Field _bottles:Int = 99
Field _y:Int=640
Field tic:Int
Field duration:Int = 1500
Field lyric:Int = 1
Method OnCreate ()
SetUpdateRate 60
End
 
' Stuff to do while running...
Method OnUpdate ()
If Millisecs()-Self.tic > Self.duration
Self.tic=Millisecs()
If Self.lyric= 4 Then Self._bottles-=1
Self.lyric+=1
 
 
End If
End
 
' Drawing code...
 
Method OnRender ()
Cls
 
Select Self.lyric
Case 1
DrawText(_bottles+" bottles of beer on the wall",10,10)
Case 2
DrawText(_bottles+" bottles of beer",10,10)
Case 3
If Self._bottles > 1
DrawText("take one down",10,10)
Else
DrawText("take it down",10,10)
End If
Case 4
DrawText("Pass it around",10,10)
Case 5
If Self._bottles>0
DrawText(Self._bottles+" bottles of beer on the wall",10,10)
Else
DrawText("no more bottles of beer on the wall",10,10)
End If
Case 6
If Self._bottles>0
Self.lyric=1'DrawText(Self._bottles+" bottles of beer on the wall",10,10)
Else
DrawText("no more bottles of beer",10,10)
End if
Case 7
DrawText("go to the store",10,10)
 
Case 8
DrawText("and buy some more",10,10)
Case 9
Self._bottles=99
DrawText(_bottles+" more bottles of beer on the wall",10,10)
Case 10
Self.lyric=1
End Select
 
End
 
 
End
 
 
 

[edit] MOO

bottles = 99;
while (bottles > 0)
unit = (bottles == 1 ? "bottle" | "bottles");
player:tell(bottles, " ", unit, " of beer on the wall.");
player:tell(bottles, " ", unit, " of beer.");
player:tell("Take one down, pass it around.");
bottles = bottles - 1;
endwhile
player:tell("0 bottles of beer on the wall.");

[edit] MoonScript

p = (i) ->
i != 1 and 's' or ''
 
for b = 99,1,-1
for i = 1,4
print if i == 3
'Take one down, pass it around'
else
string.format '%s bottle%s of beer%s',
i < 4 and b or b-1,
i < 4 and (p b) or (p b-1),
i%3 == 1 and ' on the wall' or ''
io.write '\n'

[edit] MUMPS

[edit] Recursive

beer(n)	If n<1 Write "No bottles of beer on the wall... " Quit
Write !!,n," bottle",$Select(n=1:"",1:"s")," of beer on the wall."
Write !,n," bottle",$Select(n=1:"",1:"s")," of beer."
Write !,"Take one down, pass it around."
Do beer(n-1)
Quit
 
Do beer(99)

[edit] Iterative

beer(n)	If n<1 Write "No bottles of beer on the wall... " Quit
Write !!,n," bottle",$Select(n=1:"",1:"s")," of beer on the wall."
Write !,n," bottle",$Select(n=1:"",1:"s")," of beer."
Write !,"Take one down, pass it around."
Quit
 
For ii=99:-1:0 Do beer(ii)

[edit] NASL

bottles = 99;
repeat {
display(bottles, ' bottles of beer on the wall\n');
display(bottles, ' bottles of beer\n');
display('Take one down, pass it around\n');
display(--bottles, ' bottles of beer on the wall\n\n');
} until bottles < 1;

[edit] Nemerle

using System;
using System.Console;
 
module Bottles
{
Sing(x : int, bev = "beer", surface = "wall") : void
{
match(x)
{
|0 => WriteLine($"No more bottles of $bev on the $surface, no more bottles of $bev");
WriteLine($"Go to the store and get some more $bev, 99 bottles of $bev on the $surface")
|1 => WriteLine($"One bottle of $bev on the $surface, one bottle of $bev");
WriteLine($"Take it down, pass it around, no more bottles of $bev on the $surface")
|_ => WriteLine($"$x bottles of $bev on the $surface, $x bottles of $bev");
WriteLine($"Take one down and pass it around, $(x-1) bottles of $bev on the $surface")
}
}
 
Main() : void
{
foreach (i in [99, 98 .. 0])
Sing(i)
}
}

[edit] NetRexx

 
beer = "bottles of beer on the wall"
removeOne = "Take one down, pass it arround,"
say 99 beer","
say 99 beer.subword(1,3)","
loop i = 98 to 2 by -1
say removeOne
say i beer"."
say
say i beer","
say i beer.subword(1,3)","
end
lastCall = "bottle" beer.delword(1,1)
say removeOne
say i lastCall"."
say
say i lastCall","
say i lastCall.subword(1,3)","
say removeOne
say "No more" beer
 

[edit] NewLISP

See 99 Bottles of Beer/Lisp

[edit] Nial

line is fork [
0=, 'No more bottles of beer' first,
1=, 'One bottle of beer' first,
link [string,' bottles of beer' first]
]
 
verse is link [
line, ' on the wall, ' first,line,
'. Take it down and pass it around, ' first,
line (-1+),'on the wall. ' first
]
 
bottles is iterate (write verse) reverse count

[edit] Nimrod

proc GetBottleNumber(n: int): string =
var bs: string
if n == 0:
bs = "No more bottles"
elif n == 1:
bs = "1 bottle"
else:
bs = $n & " bottles"
return bs & " of beer"
 
for bn in countdown(99, 1):
var cur = GetBottleNumber(bn)
echo(cur, " on the wall, ", cur, ".")
echo("Take one down and pass it around, ", GetBottleNumber(bn-1), " on the wall.\n")
 
echo "No more bottles of beer on the wall, no more bottles of beer."
echo "Go to the store and buy some more, 99 bottles of beer on the wall."

other:

from strutils import format
 
for i in countdown(99, 1):
case i
of 3..99:
echo format("""$1 bottles of beer on the wall
$1 bottles of beer
Take one down, pass it around
$2 bottles of beer on the wall""", i, i-1)
of 2:
echo format("""$1 bottles of beer on the wall
$1 bottles of beer
Take one down, pass it around
$2 bottle of beer on the wall""", i, i-1)
of 1:
echo format("""$1 bottle of beer on the wall
$1 bottle of beer
Take one down, pass it around
No more bottles of beer on the wall""", i)
else:
discard

compact:

from strutils import format
 
proc pluralize(a: int): string =
if a > 1 or a == 0: return "s"
else: return ""
 
for i in countdown(99, 1):
echo format("""$1 bottle$3 of beer on the wall
$1 bottle$3 of beer
Take one down, pass it around
$2 bottle$4 of beer on the wall""", i, i-1, pluralize(i), pluralize(i-1))

organized:

from strutils import format
 
var verse = """$1 bottle$3 of beer on the wall
$1 bottle$3 of beer
Take one down, pass it around
$2 bottle$4 of beer on the wall"""
 
proc pluralize(a: int): string =
if a > 1 or a == 0: return "s"
else: return ""
 
for i in countdown(99, 1):
echo format(verse, i, i-1, pluralize(i), pluralize(i-1))

[edit] Objective-C

#import <Foundation/Foundation.h>
 
int main()
{
@autoreleasepool {
int bottles = 99;
do
{
NSLog(@"%i bottles of beer on the wall\n", bottles);
NSLog(@"%i bottles of beer\n", bottles);
NSLog(@"Take one down, pass it around\n");
NSLog(@"%i bottles of beer on the wall\n\n", --bottles);
} while (bottles > 0);
 
}
return 0;
}

[edit] Oberon-2

MODULE b99;
 
IMPORT Out;
 
VAR nr : INTEGER;
 
BEGIN
nr := 99;
REPEAT
Out.Int (nr, 4);
Out.String (" bottles of beer on the wall");
Out.Ln;
Out.Int (nr, 4);
Out.String (" bottles of beer");
Out.Ln;
Out.String ("Take one down, pass it around");
Out.Ln;
DEC (nr);
Out.Int (nr, 4);
Out.String (" bottles of beer on the wall");
Out.Ln;
Out.Ln
UNTIL nr = 0
END b99.

[edit] OCaml

for n = 99 downto 1 do
Printf.printf "%d bottles of beer on the wall\n" n;
Printf.printf "%d bottles of beer\n" n;
Printf.printf "Take one down, pass it around\n";
Printf.printf "%d bottles of beer on the wall\n\n" (pred n);
done

Recursive version that handles plurals.

let verse n = 
let
line2 = function
| 0 -> "No more bottles of beer"
| 1 -> "1 bottle of beer"
| n -> string_of_int n ^ " bottles of beer"
in
let
line1or4 y = line2 y ^ " on the wall"
in
let
line3 = function
| 1 -> "Take it down, pass it around"
| _ -> "Take one down, pass it around"
in
line1or4 n ^ "\n" ^
line2 n ^ "\n" ^
line3 n ^ "\n" ^
line1or4 (n-1) ^ "\n";;
 
let rec beer n =
print_endline (verse n);
if n > 1 then beer (n-1);;
 
beer 99;;

[edit] Octave

function bottles(n)
bottle = "bottle";
ofbeer = "of beer";
wall = "on the wall";
for i = n:-1:0
if ( i == 1 )
s = "";
else
s = "s";
endif
for j = 0:1
w = wall;
if ( j == 1 )
w = "";
endif
printf("%d %s%s %s %s\n",\
i, bottle, s, ofbeer, w);
endfor
printf("Take one down, pass it around\n");
endfor
endfunction
 
bottles(99);

[edit] OOC

 
sing_line: func (b: Int, suffix: Bool) {
"#{b > 0 ? "#{b}" : "No more"} bottle#{b == 1 ? "" : "s"}" print()
" of beer#{suffix ? " on the wall" : ""}" println()
}
 
sing_verse: func (b: Int) {
println()
sing_line(b, true)
sing_line(b, false)
if (b > 0) {
"Take one down, pass it around" println()
} else {
"Go to the store and buy some more" println()
b += 100
}
sing_line(b-1, true)
}
 
main: func {
b := 100
while (b > 0) {
sing_verse(--b)
}
}
 

[edit] ooRexx

The rexx example below runs unchanged on ooRexx

[edit] OpenEdge/Progress

DEFINE VARIABLE amountofbottles AS INTEGER NO-UNDO INITIAL 99.
&GLOBAL-DEFINE bbm bottles OF beer
&GLOBAL-DEFINE bbs bottle OF beer
&GLOBAL-DEFINE otw ON the wall
&GLOBAL-DEFINE tow Take one DOWN AND pass it around,
&GLOBAL-DEFINE gts Go TO the store AND buy some more,
FUNCTION drinkBottle RETURNS INTEGER PRIVATE (INPUT bc AS INTEGER) FORWARD.
 
OUTPUT TO OUTPUT.txt.
drinkBottle(amountofbottles).
OUTPUT CLOSE.
 
FUNCTION drinkBottle RETURNS INTEGER.
IF bc >= 0 THEN DO:
CASE bc:
WHEN 2 THEN
PUT UNFORMATTED bc " {&bbm} {&otw}, " bc " {&bbm}" SKIP
"{&tow} " bc - 1 " {&bbs} {&otw}" SKIP.
WHEN 1 THEN
PUT UNFORMATTED bc " {&bbs} {&otw}, " bc " {&bbs}" SKIP
"{&tow} no more {&bbm} {&otw}" SKIP.
WHEN 0 THEN
PUT UNFORMATTED "no more" " {&bbm} {&otw}, no more {&bbm}" SKIP
"{&gts} " amountofbottles " {&bbm} {&otw}" SKIP.
OTHERWISE
PUT UNFORMATTED bc " {&bbm} {&otw}, " bc " {&bbm}" SKIP
"{&tow} " bc - 1 " {&bbm} {&otw}" SKIP.
END CASE.
drinkBottle(bc - 1).
RETURN bc.
END.
RETURN 0.
END FUNCTION.

[edit] Order

These examples are taken directly from a much longer tutorial in the Order documentation, which explains the construction of the solution to this problem in great detail.

[edit] "Pure" Order

This solution uses only Order language constructs to generate and manipulate tokens:

#include "order/interpreter.h"
 
ORDER_PP
(8let((8B, 8fn(8N,
8cond((8greater(8N, 1),
8separate(8N, 8quote(bottles)))
(8equal(8N, 1),
8quote(1 bottle))
(8else,
8quote(no more bottles))))),
8for_each_in_range
(8fn(8N,
8print(8ap(8B, 8N) (of beer on the wall,) 8space
8ap(8B, 8N) (of beer,) 8space
(take one down, pass it around,) 8space
8ap(8B, 8dec(8N)) (of beer on the wall.))),
100, 1)))

[edit] C Preprocessor

...but since most of the logic is simple substitution, it makes more sense (and is significantly more efficient) to make the C Preprocessor do most of the work without the help of the Order interpreter. This version shows how to integrate normal C Preprocessor macros into an Order program:

#include "order/interpreter.h"
 
#define GEN_phrase(N_bottles, N_minus_1_bottles) \
N_bottles of beer on the wall, \
N_bottles of beer, take one down, pass it around, \
N_minus_1_bottles of beer on the wall.

 
#define ORDER_PP_DEF_8bottles \
ORDER_PP_FN(8fn(8N, \
8cond((8greater(8N, 1), \
8separate(8N, 8quote(bottles))) \
(8equal(8N, 1), \
8quote(1 bottle)) \
(8else, \
8quote(no more bottles)))))

 
ORDER_PP(8for_each_in_range
(8fn(8N,
8emit(8quote(GEN_phrase),
8tuple(8bottles(8N),
8bottles(8dec(8N))))),
100, 1))
 
#undef GEN_phrase

Either example could obviously also form the core of a C solution (demonstrating the intended use of Order).

[edit] Oxygene

 
namespace ConsoleApplication2;
 
interface
 
type
ConsoleApp = class
public
class method Main(args: array of String);
end;
 
implementation
 
method bottles(number: Integer): String;
begin
if (number = 1) then
Result := "bottle"
else
Result := "bottles";
end;
 
class method ConsoleApp.Main(args: array of String);
begin
for n: Integer := 99 downto 1 do
begin
Console.WriteLine("{0} {1} of beer on the wall,",n,bottles(n));
Console.WriteLine("{0} {1} of beer,",n,bottles(n));
Console.WriteLine("Take one down, and pass it around,");
Console.WriteLine("{0} {1} of beer on the wall.",n-1,bottles(n-1));
Console.WriteLine();
end;
Console.ReadKey();
end;
 
end.
 


[edit] Oz

[edit] Constraint Programming

Note: In real life, you would never solve a simple iterative task like this with constraint programming. This is just for fun.

declare
%% describe the possible solutions of the beer 'puzzle'
proc {BeerDescription Solution}
N = {FD.int 1#99} %% N is an integer in [1, 99]
in
%% distribute starting with highest value
{FD.distribute generic(value:max) [N]}
 
Solution =
{Bottles N}#" of beer on the wall\n"#
{Bottles N}#" bottles of beer\n"#
"Take one down, pass it around\n"#
{Bottles N-1}#" of beer on the wall\n"
end
 
%% pluralization
proc {Bottles N Txt}
cond N = 1 then Txt ="1 bottle"
else Txt = N#" bottles"
end
end
in
%% show all solutions to the 'puzzle'
{ForAll {SearchAll BeerDescription}
System.showInfo}

[edit] Iterative

declare
fun {Bottles N}
if N == 1 then "1 bottle"
else N#" bottles"
end
end
in
for I in 99..1;~1 do
{System.showInfo
{Bottles I}#" of beer on the wall\n"#
{Bottles I}#" bottles of beer\n"#
"Take one down, pass it around\n"#
{Bottles I-1}#" of beer on the wall\n"}
end

[edit] PARI/GP

forstep(n=99,3,-1,
print(n" bottles of beer on the wall");
print(n" bottles of beer");
print("Take one down, pass it around");
print(n-1," bottles of beer on the wall\n")
);
print("2 bottles of beer on the wall\n2 bottles of beer\nTake one down, pass it around\n1 bottle of beer on the wall\n");
print("1 bottle of beer on the wall\n1 bottle of beer\nTake one down, pass it around\nNo more bottles of beer on the wall")

[edit] Pascal

See 99 Bottles of Beer/Pascal

[edit] Perl

#!/usr/bin/perl -w
 
my $verse = <<"VERSE";
100 bottles of beer on the wall,
100 bottles of beer!
Take one down, pass it around!
99 bottles of beer on the wall!
 
VERSE

 
{
$verse =~ s/(\d+)/$1-1/ge;
$verse =~ s/\b1 bottles/1 bottle/g;
my $done = $verse =~ s/\b0 bottle/No bottles/g; # if we make this replacement, we're also done.
 
print $verse;
redo unless $done;
}

Alternatively:

for $n (reverse(0..99))
{
$bottles = sprintf("%s bottle%s of beer on the wall\n",(($n==0)?"No":$n), (($n==1)?"":"s"));
print( (($n==99)?"":"$bottles\n") .
(($n==0)?"":(substr(${bottles}x2,0,-12) . "\nTake one down, pass it around\n")) );
}

Correct grammar and nice spacing in modern perl:

use 5.10.0;                                                                        
 
$num = 99;
while ($num > 0) {
my $s = "s" unless ($num == 1);
say "$num bottle$s of beer on the wall, $num bottle$s of beer";
$num--;
my $s = "s" unless ($num == 1);
$num = "No more" if ($num == 0);
say "Take one down, pass it around, $num bottle$s of beer on the wall\n"
}
 
say "No more bottles of beer on the wall, no more bottles of beer.";
say "Go to the store and buy some more, 99 bottles of beer on the wall.";

Using perl5 as a DSL factory leveraging $_'s global nature:

 
#!/usr/bin/env perl
use strict;
use warnings;
 
sub bottles() { sprintf qq{%s bottle%s of beer}
, $_ || 'No'
, $_==1 ? '' : 's';
}
sub store() { $_=99; qq{Go to the store, buy some more...\n}; }
sub wall() { qq{ on the wall\n} }
sub take() { $_-- ? qq{Take one down, pass it around\n} : store }
do { print bottles, wall
, bottles, qq{\n}
, take
, bottles, qq{\n\n}
} for reverse 0..99;

[edit] Perl 6

[edit] A Simple Way

my $b = 99;
 
sub b($b) {
"$b bottle{'s'.substr($b == 1)} of beer";
}
 
repeat while --$b {
.say for "&b($b) on the wall",
b($b),
'Take one down, pass it around',
"&b($b-1) on the wall",
'';
}
 

[edit] A Clearer Way

Similar to "A Simple Way", but with proper variable and subroutine naming, declarator documentation, strongly-typed function definition, default parameters, better code reuse, and clearer external ternary logic instead of misusing substr side-effects within an interpolated string.

 
#= Sings a verse about a certian number of beers, possibly on a wall.
sub sing(
Int $number, #= Number of bottles of beer.
Bool $has_wall = False #= Mention that the beers are on a wall?
) {
my $quantity = $number == 0 ?? "No more" !! $number;
my $plural = $number == 1 ?? "" !! "s";
my $wall = $has_wall ?? " on the wall" !! "";
return "{$quantity} bottle{$plural} of beer{$wall}"
}
 
for 99...1 -> $bottles {
.say for
sing($bottles, True),
sing($bottles),
"Take one down, pass it around",
sing($bottles-1, True),
"";
}
 

[edit] A More Extravagant Way

Works with: Rakudo version #22 "Thousand Oaks"
my @quantities = (99 ... 1), 'No more', 99;
my @bottles = 'bottles' xx 98, 'bottle', 'bottles' xx 2;
my @actions = 'Take one down, pass it around' xx 99,
'Go to the store, buy some more';
 
for @quantities Z @bottles Z @actions Z
@quantities[1 .. *] Z @bottles[1 .. *]
-> $a, $b, $c, $d, $e {
say "$a $b of beer on the wall";
say "$a $b of beer";
say $c;
say "$d $e of beer on the wall\n";
}

[edit] PHL

Translation of: C
module bottles;
extern printf;
 
@Integer main [
@Integer bottles = 99;
do
{
printf("%u bottles of beer on the wall\n", bottles);
printf("%u bottles of beer\n", bottles);
printf("Take one down, pass it around\n");
bottles = bottles::dec;
printf("%u bottles of beer on the wall\n\n", bottles);
} while(bottles > 0);
return 0;
]

[edit] PHP

<?php
$plural = 's';
foreach (range(99, 1) as $i) {
echo "$i bottle$plural of beer on the wall,\n";
echo "$i bottle$plural of beer!\n";
echo "Take one down, pass it around!\n";
if ($i - 1 == 1)
$plural = '';
 
if ($i > 1)
echo ($i - 1) . " bottle$plural of beer on the wall!\n\n";
else
echo "No more bottles of beer on the wall!\n";
}
?>

[edit] shorter way

<?php
foreach(range(99,1) as $i) {
$p = ($i>1)?"s":"";
echo <<< EOV
$i bottle$p of beer on the wall
$i bottle$p of beer
Take one down, pass it around
 
 
EOV
;
}
echo "No more Bottles of beer on the wall";
?>

[edit] modifing way:

<?php
$verse = <<<VERSE
100 bottles of beer on the wall,
100 bottles of beer!
Take one down, pass it around!
99 bottles of beer on the wall!
 
 
VERSE
;
 
foreach (range(1,99) as $i) { // loop 99 times
$verse = preg_replace('/\d+/e', '$0 - 1', $verse);
$verse = preg_replace('/\b1 bottles/', '1 bottle', $verse);
$verse = preg_replace('/\b0 bottle/', 'No bottles', $verse);
 
echo $verse;
}
?>

[edit] ultra compact alternative

supports grammar and has no leading and trailing new lines or spaces. Also one does not have to close the <?php tag, it is even recommended not to close it, if closing it is not necessary

<?php
for($i=100;$i>0;$i--){
$p2=$i." bottle".(($i>1)?"s":"")." of beer";
$p1=$p2." on the wall\n";
$p3="Take one down, pass it around\n";
echo (($i<100)?$p1."\n":"").$p1.$p2."\n".$p3.(($i<2)?($i-1).substr($p1,1,28):"");
}

[edit] gettext alternative

supports grammar and translations.

<?php
 
$bottles = 99;
 
while ($bottles > 0) {
printf(ngettext('%d bottle', '%d bottles', $bottles) . " of beer on the wall\n", $bottles); //X bottles of beer on the wall
printf(ngettext('%d bottle', '%d bottles', $bottles) . " of beer\n", $bottles); //X bottles of beer
printf("Take one down, pass it around\n"); //Take one down, pass it around
 
$bottles--;
 
if ($bottles > 0) {
printf(ngettext('%d bottle', '%d bottles', $bottles) . " of beer on the wall\n\n", $bottles); //X bottles of beer on the wall
}
}
printf('No more bottles of beer on the wall'); //No more bottles of beer on the wall

[edit] PicoLisp

See 99 Bottles of Beer/Lisp

[edit] Piet

See 99 Bottles of Beer/EsoLang

[edit] Pike

int main(){
for(int i = 99; i > 0; i--){
write(i + " bottles of beer on the wall, " + i + " bottles of beer.\n");
write("Take one down and pass it around, " + (i-1) + " bottles of beer on the wall.\n\n");
}
write("No more bottles of beer on the wall, no more bottles of beer.\n");
write("Go to the store and buy some more, 99 bottles of beer on the wall.\n");
}

alternate version:

// disclaimer: i prefer gingerale
 
void main()
{
array numbers = ({ "no more", "one", "two", "three", "four", "five", "six", "seven",
"eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen" });
array decades = ({ "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty",
"ninety" });
 
foreach (decades;; string decade)
{
numbers += decade+(({ "" }) + numbers[1..9])[*];
}
numbers = reverse(numbers);
 
array bottles = ((numbers[*]+" bottles of ale on the wall, ")[*] +
(numbers[*]+" bottles of ale.\n")[*]);
 
bottles[-2] = replace(bottles[-2], "one bottles", "one bottle");
 
string song = bottles * "take one down, pass it around,\n";
write(song);
}

[edit] PIR

Works with: Parrot version Tested with 2.4.0
.sub sounding_smart_is_hard_after_drinking_this_many
.param int b
if b == 1 goto ONE
.return(" bottles ")
ONE:
.return(" bottle ")
end
.end
 
.sub main :main
.local int bottles
.local string b
bottles = 99
LUSH:
if bottles == 0 goto DRUNK
b = sounding_smart_is_hard_after_drinking_this_many( bottles )
print bottles
print b
print "of beer on the wall\n"
print bottles
print b
print "of beer\nTake one down, pass it around\n"
dec bottles
b = sounding_smart_is_hard_after_drinking_this_many( bottles )
print bottles
print b
print "of beer on the wall\n\n"
goto LUSH
DRUNK:
end
.end

[edit] PlainTeX

\def\ifbeer{\ifnum\number\bottles}
\def\beers{
\par\ifbeer>0 \the\bottles~\else No more \fi
bottle\ifbeer=1\else s\fi~of beer%
}
 
\def\take #1 down,{
\par\advance\bottles by -#1
Take #1 down, pass it around,\par
}
 
\long\def\verse{
\beers~on the wall, \beers.
\take 1 down, % curious TeX \def syntax
\beers~on the wall.
\bigskip
}
 
\newcount\bottles\bottles99
\loop\verse
\ifnum\number\bottles>0\repeat
 
\bye

[edit] Pop11

define bootles(n);
while n > 0 do
printf(n, '%p bottles of beer on the wall\n');
printf(n, '%p bottles of beer\n');
printf('Take one down, pass it around\n');
n - 1 -> n;
printf(n, '%p bottles of beer on the wall\n');
endwhile;
enddefine;
 
bootles(99);

[edit] PostScript

%!PS
/Helvetica findfont 9 scalefont setfont
 
/printBeer {
dup
20 string cvs show
( bottle) show
1 ne
{ (s) show } if
( of beer) show
} def
 
/printVerse {
dup
dup
dup
7 mul
50 add
/yPos exch def
15 yPos moveto
printBeer
( on the wall, ) show
printBeer
(. ) show
(Take one down, pass it around, ) show
1 sub
printBeer
( on the wall. ) show
} def
 
/song {
100 -1 1 { printVerse } for
} def
 
song
showpage
%%EOF

[edit] PowerShell

See 99 Bottles of Beer/Shell

[edit] ProDOS

See 99 Bottles of Beer/Shell

[edit] Prolog

See 99 Bottles of Beer/Prolog

[edit] Python

See 99 Bottles of Beer/Python


[edit] Qore

[edit] Simple Solution

#!/usr/bin/env qore
 
%enable-all-warnings
 
for (my $i = 99; $i > 0; $i--) {
printf("%d bottles of beer on the wall\n", $i);
printf("%d bottles of beer\n", $i);
printf("take one down, pass it around\n");
printf("%d bottles of beer on the wall\n", $i);
}

[edit] Concurrent (Unordered) Solution

#!/usr/bin/env qore                                                                        
 
%enable-all-warnings
%require-types
 
# global variables (truly shared among threads) must be declared with "our" keyword
%require-our
 
our Counter $count();
 
sub t() {
on_exit {
$count.dec();
}
my int $i = gettid()-1;
printf("%d bottles of beer on the wall\n", $i);
printf("%d bottles of beer\n", $i);
printf("take one down, pass it around\n");
printf("%d bottles of beer on the wall\n", $i);
}
 
#-- following run by main thread
for (my int $i = 99; $i > 0; $i--) {
$count.inc();
background t();
}
 
$count.waitForZero();

[edit] Quill

bottles := void(int count) {
(count > 0) if {
new_count := count - 1;
(
count, " bottles of beer on the wall", nl,
count, " bottles of beer", nl,
"Take one down, pass it around", nl,
new_count, " bottles of beer on the wall"
) print;
new_count bottles
} else {
"No more bottles of beer on the wall!" print
}
};
99 bottles

[edit] R

[edit] Simple looping solution

#a naive function to sing for N bottles of beer...
 
song = function(bottles){
 
for(i in bottles:1){ #for every integer bottles, bottles-1 ... 1
 
cat(bottles," bottles of beer on the wall \n",bottles," bottles of beer \nTake one down, pass it around \n",
bottles-1, " bottles of beer on the wall \n"," \n" ,sep="") #join and print the text (\n means new line)
 
bottles = bottles - 1 #take one down...
 
}
 
}
 
song(99)#play the song by calling the function

[edit] Vector solutions

#only one line!
cat(paste(99:1,ifelse((99:1)!=1," bottles"," bottle")," of beer on the wall\n",99:1,ifelse((99:1)!=1," bottles"," bottle")," of beer\n","Take one down, pass it around\n",98:0,ifelse((98:0)!=1," bottles"," bottle")," of beer on the wall\n\n",sep=""),sep="")
 
#alternative
cat(paste(lapply(99:1,function(i){paste(paste(rep(paste(i,' bottle',if(i!=1)'s',' of beer',sep=''),2),collapse =' on the wall\n'),'Take one down, pass it around',paste(i-1,' bottle',if(i!=2)'s',' of beer on the wall',sep=''), sep='\n')}),collapse='\n\n'))

[edit] Racket

 
#lang racket
(define (sing bottles)
(define (plural n) (~a n " bottle" (if (= n 1) "" "s")))
(printf "~a of beer on the wall\n~a of beer\n~
Take one down, pass it around\n~a of beer on the wall\n\n"
(plural bottles) (plural bottles) (plural (sub1 bottles)))
(unless (= 1 bottles) (sing (sub1 bottles))))
(sing 100)
 

[edit] RapidQ

 
dim nBott as integer
nBott = 99
 
While nBott > 0
Print(str$(nBott ) + " bottle" + iif(nBott=1, "", "s") + " of beer on the wall")
Print(str$(nBott ) + " bottle" + iif(nBott=1, "", "s") + " of beer")
Print("Take one down, pass it around")
nBott--
Print(str$(nBott ) + " bottle" + iif(nBott=1, "", "s") + " of beer on the wall" + chr$(10))
Wend
 
while inkey$="":wend
end
 

[edit] Rascal

 
module demo::basic::Bottles
 
import IO;
 
str bottles(0) = "no more bottles";
str bottles(1) = "1 bottle";
default str bottles(int n) = "<n> bottles";
 
public void sing(){
for(n <- [99 .. 1]){
println("<bottles(n)> of beer on the wall, <bottles(n)> of beer.");
println("Take one down, pass it around, <bottles(n-1)> of beer on the wall.\n");
}
println("No more bottles of beer on the wall, no more bottles of beer.");
println("Go to the store and buy some more, 99 bottles of beer on the wall.");
}
 

[edit] Raven

99 0 1 range each as $i
$i 1 = if
"bottle" as $b
else
"bottles" format as $b
$b $i "%d %s of beer on the wall,\n" print
$b $i "%d %s of beer,\n" print
"Take one down, pass it around,\n" print
$i 2 = if
"1 bottle"
else
$i 1 - "%d bottles" format
"%s of beer on the wall.\n\n" print
Output:

Last couple of stanzas are:

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

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

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

[edit] REBOL

rebol [
Title: "99 Bottles of Beer"
Author: oofoe
Date: 2009-12-11
URL: http://rosettacode.org/wiki/99_Bottles_of_Beer
]

 
; The 'bottles' function maintains correct grammar.
 
bottles: func [n /local b][
b: either 1 = n ["bottle"]["bottles"]
if 0 = n [n: "no"]
reform [n b]
]
 
for n 99 1 -1 [print [
bottles n "of beer on the wall" crlf
bottles n "of beer" crlf
"Take one down, pass it around" crlf
bottles n - 1 "of beer on the wall" crlf
]]

Output (selected highlights):

99 bottles of beer on the wall    2 bottles of beer on the wall 
99 bottles of beer                2 bottles of beer             
Take one down, pass it around     Take one down, pass it around 
98 bottles of beer on the wall    1 bottle of beer on the wall  
                                                                
...Continues...                   1 bottle of beer on the wall  
                                  1 bottle of beer              
                                  Take one down, pass it around 
                                  no bottles of beer on the wall

This one prints with proper grammar. "Bottles" changed to "bottle" at the end of the 2 line, and throughout the 1 line. 0 changed to "No" in the last line:

for i 99 1 -1 [ 
x: rejoin [
i b: " bottles of beer" o: " on the wall. " i b
". Take one down, pass it around. " (i - 1) b o "^/"
]
r: :replace j: "bottles" k: "bottle"
switch i [1 [r x j k r at x 10 j k r x "0" "No"] 2 [r at x 40 j k]]
print x
] halt

Here's a simple 1 line console version:

for i 99 1 -1[print rejoin[i b:" bottles of beer"o:" on the wall. "i b". Take one down, pass it around. "(i - 1)b o"^/"]]

[edit] Retro

This is based on the Forth example.

[ dup "%d bottles" puts ]
[ "1 bottle" puts ]
[ "no more bottles" puts ]
create bottles , , ,
 
: .bottles dup 2 ^math'min bottles + @ do ;
: .beer .bottles " of beer" puts ;
: .wall .beer " on the wall" puts ;
: .take "Take one down, pass it around" puts ;
: .verse .wall cr .beer cr
1- .take cr .wall cr ;
: ?dup dup 0; ;
: verses [ cr .verse dup 0 <> ] while drop ;
 
99 verses
bye

[edit] REXX

/*REXX pgm displays lyrics to the song "99 Bottles of Beer on the Wall".*/
parse arg N .; if N=='' then N=99 /*let # bottles be specified*/
 
do j=N by -1 to 1 /*start countdown & singdown*/
say j 'bottle's(j) "of beer on the wall," /*sing the #bottles of beer.*/
say j 'bottle's(j) "of beer." /* ··· and the refrain.*/
say 'Take one down, pass it around,' /*get a bottle and share it.*/
m=j-1 /*M: # bottles we have now.*/
if m==0 then m='no' /*use "no" instead of 0. */
say m 'bottle's(m) "of beer on the wall." /*sing beer bottle inventory*/
say /*blank line between verses.*/
end /*j*/
/*Not tanked? Then sing it.*/
say 'No more bottles of beer on the wall,' /*Finally! The last verse.*/
say 'no more bottles of beer.' /*this is so forlorn ··· */
say 'Go to the store and buy some more,' /*replenishment of the beer.*/
say N 'bottles of beer on the wall.' /*all is well in the tavern.*/
exit /*we're done & also sloshed.*/
/*───────────────────────────────────S subroutine───────────────────────*/
s: if arg(1)=1 then return ''; return 's' /*simple pluralizer function*/

output     Below is the first and last three verses of the song:

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

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

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

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

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

[edit] RPL/2

[edit] Simple solution

BEER
<<
99 do
dup ->str PLURAL " on the wall," + disp
dup ->str PLURAL "." + disp
"Take one down, pass it around," disp
1 -
if dup then
dup ->str
else
"No more"
end
PLURAL " on the wall." + disp
"" disp
until dup 0 == end
drop
>>
 
PLURAL
<<
" bottle" + over if 1 <> then "s" + end " of beer" +
>>

[edit] Recursive and multithreaded solution

BOTTLES
<<
// Child process is started.
100 'RECURSIVE' detach
-> PROC
<<
do PROC recv until end drop2
 
do
// Parent waits for datas sent by child.
do PROC recv until end
list-> drop dup " on the wall," + disp "." + disp
"Take one down, pass it around," disp
 
if dup 1 same not then
do PROC recv until end list-> drop
else
1 "No more bottles of beer"
end
" on the wall." + disp drop "" disp
until
1 same
end
 
// Parent waits for Child's death.
PROC wfproc
>>
>>
 
RECURSIVE
<<
while
dup
repeat
1 - dup dup ->str
if over 1 > then " bottles " else " bottle " end +
"of beer" + 2 ->list dup
// Child send datas to parent process.
send send
// Recursive function is caught.
RECURSIVE
end
>>

[edit] Ruby

plural = 's'
99.downto(1) do |i|
puts "#{i} bottle#{plural} of beer on the wall,"
puts "#{i} bottle#{plural} of beer"
puts "Take one down, pass it around!"
plural = '' if i - 1 == 1
if i > 1
puts "#{i-1} bottle#{plural} of beer on the wall!"
puts
else
puts "No more bottles of beer on the wall!"
end
end

Ruby has variable traces, so we can do

trace_var :$bottle_num do |val|
$bottles = %Q{#{val == 0 ? 'No more' : val.to_s} bottle#{val == 1 ? '' : 's'}}
end
 
($bottle_num = 99).times do
puts "#{$bottles} of beer on the wall"
puts "#{$bottles} of beer"
puts "Take one down, pass it around"
$bottle_num -= 1
puts "#{$bottles} of beer on the wall"
puts ""
end

or...

def bottles(of_beer, ending)
puts "#{of_beer} bottle#{ending} of beer on the wall,"
puts "#{of_beer} bottle#{ending} of beer"
puts "Take one down, pass it around!"
end
 
99.downto(0) do |left|
if left > 1
bottles(left, "s")
elsif left == 1
bottles(left, "")
else
puts "No more bottles of beer on the wall!"
end
end

or...

def bottles(beer, wall = false)
"#{beer>0 ? beer : "no more"} bottle#{"s" if beer!=1} of beer#{" on the wall" if wall}"
end
 
99.downto(0) do |remaining|
puts "#{bottles(remaining,true).capitalize}, #{bottles(remaining)}."
if remaining==0
print "Go to the store and buy some more"
remaining=100
else
print "Take one down, pass it around"
end
puts ", #{bottles(remaining-1,true)}.\n\n"
end

[edit] Simple solution

 
99.downto(1) do |bottles|
puts "#{bottles} bottle#{"s" if bottles != 1} of beer on the wall.",
"#{bottles} bottle#{"s" if bottles != 1} of beer.",
"Take one down, pass it around.",
"#{bottles - 1} bottle#{"s" if bottles - 1 != 1} of beer on the wall.\n\n"
end
 

[edit] Rust

Works with: rustc version 0.12.0-pre-nightly
use std::iter::range_step_inclusive;
 
trait Bottles {
fn bottles_of_beer(&self) -> Self;
fn on_the_wall(&self);
}
 
impl Bottles for int{
 
fn bottles_of_beer(&self) -> int {
match *self {
1 => print!("{} bottle of beer", self),
0 => print!("No bottles of beer"),
_ => print!("{} bottles of beer", self)
}
*self //for chaining
}
 
fn on_the_wall(&self) {
println!(" on the wall!");
}
}
 
fn main() {
for i in range_step_inclusive(99i, 1, -1) {
i.bottles_of_beer().on_the_wall();
i.bottles_of_beer();
println!("\nTake one down, pass it around...");
(i - 1).bottles_of_beer().on_the_wall();
println!("-----------------------------------");
}
}

[edit] Sather

class MAIN is
main is
s :STR;
p1 ::= "<##> bottle<#> of beer";
w  ::= " on the wall";
t  ::= "Take one down, pass it around\n";
loop i ::= 99.downto!(0);
if i /= 1 then s := "s" else s := ""; end;
#OUT + #FMT(p1 + w + "\n", i, "s");
#OUT + #FMT(p1 + "\n", i, "s");
if i > 0 then #OUT + t; end;
end;
end;
end;

[edit] Scala

See 99 Bottles of Beer/Scala

[edit] Scheme

Works with: Chicken Scheme
(define (bottles x)
(format #t "~a bottles of beer on the wall~%" x)
(format #t "~a bottles of beer~%" x)
(format #t "Take one down, pass it around~%")
(format #t "~a bottles of beer on the wall~%" (- x 1))
(if (> (- x 1) 0)
(bottles (- x 1))))

[edit] Scratch

See 99 Bottles of Beer/VPL

[edit] sed

s/.*/99 bottles of beer on the wall/
h
: b
s/^0//
/^0/q
s/^1 bottles/1 bottle/
p
s/on.*//
p
s/.*/Take one down, pass it around/
p
g
/^.[1-9]/{
h
s/^.//
y/123456789/012345678/
x
s/^\(.\).*$/\1/
G
s/\n//
h
bb
}
y/0123456789/9012345678/
h
bb

[edit] Seed7

$ include "seed7_05.s7i";
 
const proc: main is func
local
var integer: number is 0;
begin
for number range 99 downto 2 do
write( number <& " bottles of beer on the wall, ");
writeln( number <& " bottles of beer.");
write( "Take one down and pass it around, ");
writeln( pred(number) <& " bottles of beer on the wall.");
writeln;
end for;
writeln("1 bottle of beer on the wall, 1 bottle of beer.");
writeln("Take one down and pass it around, no more bottles of beer on the wall.");
writeln;
writeln("No more bottles of beer on the wall, no more bottles of beer.");
writeln("Go to the store and buy some more, 99 bottles of beer on the wall.")
end func;

[edit] Shiny

for 99 i:99-a
s: if i > 1 's' end
 
if i > 0 and i < 99 switch
if i = 6 say "A six-pack on the wall!\n" break
if i = 24 say "A carton on the wall!\n" break
say "$i bottle$s of beer on the wall!\n"
ends
 
say "$i bottle$s of beer on the wall,"
say "$i bottle$s of beer!"
say "Take one down, pass it around!"
end
say "Aww...no more bottles of beer on the wall... it must be your shout :)"

[edit] Sidef

99.downto(0).each { |i|
var bottles = "#{i == 0 ? 'No' : i} bottle#{i == 1 ? '' : 's'}";
var sentence = "#{bottles} of beer on the wall" -> say;
i > 0 && (
sentence.substr(0, bottles.length + 8).say;
"Take one down, pass it around\n".say;
);
};

Simpler:

99.downto(2).each { | n |
say "#{n} bottles of beer on the wall, #{n} bottles of beer!";
say "Take one down, pass it around, #{n - 1} bottle#{n > 2 ? 's' : ''} of beer on the wall.\n";
};
 
say "One bottle of beer on the wall, one bottle of beer!";
say "Take one down, pass it around, no more bottles of beer on the wall.";

[edit] Slate

n@(Integer traits) bottleVerse
[| nprinted |
nprinted: n printString ; ' bottle' ; (n > 1 ifTrue: ['s'] ifFalse: ['']) ; ' of beer'.
inform: nprinted ; ' on the wall.'.
inform: nprinted.
inform: 'Take one down, pass it around.'.
inform: nprinted ; ' on the wall.'.
].
 
x@(Integer traits) bottles
[
x downTo: 0 do: #bottleVerse `er
].
 
99 bottles.

[edit] Smalltalk

A straightforward approach:

Smalltalk at: #sr put: 0 ; at: #s put: 0 !
sr := Dictionary new.
sr at: 0 put: ' bottle' ;
at: 1 put: ' bottles' ;
at: 2 put: ' of beer' ;
at: 3 put: ' on the wall' ;
at: 4 put: 'Take one down, pass it around' !
99 to: 0 by: -1 do: [:v | v print.
( v == 1 ) ifTrue: [ s := 0. ]
ifFalse: [ s := 1. ].
Transcript show: (sr at:s) ; show: (sr at:2) ; show: (sr at:3) ; cr.
v print.
Transcript show: (sr at:s) ; show: (sr at:2) ; cr.
(v ~~ 0) ifTrue: [ Transcript show: (sr at:4) ; cr. ].
].

[edit] SNOBOL4

	x = 99
again output = X " bottles of beer on the wall"
output = X " bottles of beer"  ?eq(X,0) :s(zero)
output = "Take one down, pass it around"
output = (X = gt(x,0) X - 1) " bottle of beer on the wall..." :s(again)
zero output = "Go to store, get some more"
output = "99 bottles of beer on the wall"
end

[edit] Function

Works with: Macro Spitbol
Works with: CSnobol

Function version with string composition. Function returns one verse for x bottles. Correctly handles bottle/bottles.

        define('bottles(x)')
nl = char(13) char(10) ;* Win/DOS, change as needed
s2 = ' of beer'; s3 = ' on the wall'
s4 = 'Take one down, pass it around'
s5 = 'Go to the store, get some more' :(bottles_end)
bottles s1 = (s1 = ' Bottle') ne(x,1) 's'
output = nl x s1 s2 s3 nl x s1 s2
x = gt(x,0) x - 1 :f(done)
s1 = (s1 = ' Bottle') ne(x,1) 's'
output = s4 nl x s1 s2 s3 :(return)
done output = s5 nl 99 s1 s2 s3 :(return)
bottles_end
 
* # Test and display, only 2 bottles!
n = 2
loop bottles(n); n = gt(n,0) n - 1 :s(loop)
end

Output:

2 Bottles of beer on the wall
2 Bottles of beer
Take one down, pass it around
1 Bottle of beer on the wall

1 Bottle of beer on the wall
1 Bottle of beer
Take one down, pass it around
0 Bottles of beer on the wall

0 Bottles of beer on the wall
0 Bottles of beer
Go to the store, get some more
99 Bottles of beer on the wall

[edit] SNUSP

See 99 Bottles of Beer/EsoLang

[edit] Sparkling

var bottles = 99;
 
do {
printf("%u bottles of beer on the wall\n", bottles);
printf("%u bottles of beer\n", bottles);
printf("Take one down, pass it around\n");
printf("%u bottles of beer on the wall\n\n", --bottles);
} while(bottles > 1);
 
printf("1 bottle of beer on the wall\n1 bottle of beer\nTake it down, pass it around\n0 bottles of beer on the wall\n");

[edit] SQL

 
SELECT
( 100 - level ) || ' bottle' || CASE 100 - level WHEN 1 THEN '' ELSE 's' END || ' of beer on the wall'
|| chr(10)
|| ( 100 - level ) || ' bottle' || CASE 100 - level WHEN 1 THEN '' ELSE 's' END || ' of beer'
|| chr(10)
|| 'Take one down, pass it around'
|| chr(10)
|| ( 99 - level ) || ' bottle' || CASE 99 - level WHEN 1 THEN '' ELSE 's' END || ' of beer on the wall'
FROM dual CONNECT BY level <= 99;
 
 
 
 
DELIMITER $$
DROP PROCEDURE IF EXISTS bottles_$$
CREATE PROCEDURE `bottles_`(INOUT bottle_count INT, INOUT song text)
BEGIN
DECLARE bottles_text VARCHAR(30);
 
 
IF bottle_count > 0 THEN
 
 
IF bottle_count != 1 THEN
SET bottles_text := ' bottles of beer ';
ELSE SET bottles_text = ' bottle of beer ';
END IF;
 
SELECT concat(song, bottle_count, bottles_text, ' \n') INTO song;
SELECT concat(song, bottle_count, bottles_text, 'on the wall\n') INTO song;
SELECT concat(song, 'Take one down, pass it around\n') INTO song;
SELECT concat(song, bottle_count -1 , bottles_text, 'on the wall\n\n') INTO song;
SET bottle_count := bottle_count -1;
CALL bottles_( bottle_count, song);
END IF;
END$$
 
SET @bottles=99;
SET max_sp_recursion_depth=@bottles;
SET @song='';
CALL bottles_( @bottles, @song);
SELECT @song;
 

This Statement does also work with T-SQL, but only up to 32 beers

 
CREATE PROCEDURE bottles
@bottle_count INT,
@song VARCHAR(MAX)
 
AS
BEGIN
 
DECLARE @bottles_text VARCHAR(MAX);
 
 
IF @bottle_count > 0
BEGIN
IF @bottle_count != 1
BEGIN
SET @bottles_text = ' bottles of beer ';
END
ELSE
BEGIN
SET @bottles_text = ' bottle of beer ';
END
 
 
 
SET @song = @song + CAST(@bottle_count AS VARCHAR) + @bottles_text + '\n';
 
SET @song = @song + CAST(@bottle_count AS VARCHAR) + @bottles_text + 'on the wall\n'
SET @song = @song + 'Take one down, pass it around\n'
SET @song = @song + CAST((@bottle_count - 1) AS VARCHAR) + @bottles_text + 'on the wall\n'
 
 
SET @bottle_count = (@bottle_count - 1);
 
 
 
 
EXEC bottles @bottle_count, @song
 
END
ELSE
SELECT @song AS 'RESULT'
END
 
/*****
AND IN ORDER TO CALL PROCEDURE:
****/

EXECUTE bottles 31, '';
 
 

[edit] Squirrel

 
function rec(bottles)
{
if (bottles > 0)
{
print(bottles+" bottles of beer on the wall\n")
print(bottles+" bottles of beer\n");
print("Take one down, pass it around\n");
print(--bottles+" bottles of beer on the wall\n\n")
return rec(bottles);
}
print("No more bottles of beer on the wall, no more bottles of beer\n");
print("Go to the store and get some more beer, 99 bottles of beer on the wall\n");
}
 
rec(99);
 

[edit] Standard ML

fun bottles 0 = ()
| bottles x = ( print (Int.toString x ^ " bottles of beer on the wall\n");
print (Int.toString x ^ " bottles of beer\n");
print "Take one down, pass it around\n";
print (Int.toString (x-1) ^ " bottles of beer on the wall\n");
bottles (x-1)
)

[edit] Suneido

i = 99
while (i > 0)
{
Print(i $ ' bottles of beer on the wall')
Print(i $ ' bottles of beer')
Print('Take one down, pass it around')
--i
if i is 0
Print('Ahh poo, we are out of beer\n')
else
Print(i $ ' bottles of beer on the wall\n')
}

[edit] Swift

 
var bottles = 99
 
if bottles<=99{
do{
println("\n\n\(bottles) bottles of beer on the wall, \(bottles) bottles of beer.")
bottles=bottles-1
println("Take one down and pass it around, \(bottles) bottles of beer on the wall.\n\n")
}while bottles>1
}
if bottles==1{
println("\(bottles) bottle of beer on the wall, \(bottles) bottle of beer.\nTake one down and pass it around, no more bottles of beer on the wall.\n\n")
bottles=bottles-1
}
if bottles==0{
println("No more bottles of beer on the wall, no more bottles of beer.\n\n")
 
}
else{
//If "var bottles" > 99 (first line)
println("It's unpossible to have so many bottles of beer on the wall")
}
 
 

[edit] Tcl

See 99 Bottles of Beer/Tcl

[edit] Thyrd

See 99 Bottles of Beer/VPL

[edit] TIScript

 
var beer = 99;
while (beer > 0)
{
stdout.printf( "%d bottles of beer on the wall\n", beer);
stdout.printf( "%d bottles of beer\n", beer);
stdout.println( "Take one down, pass it around" );
stdout.printf( "%d bottles of beer on the wall\n", --beer );
}
 

[edit] TorqueScript

 
for(%i = 99; %i >= 0; %i--)
{
%n = %i - 1;
echo(%i SPC (%n == 1 ? "bottle" : "bottles") SPC "of beer on the wall ~");
echo("Take one down, pass it around,");
echo(%n SPC (%i == 1 ? "bottle" : "bottles") SPC "of beer on the wall.");
}
 

[edit] TUSCRIPT

 
$$ MODE TUSCRIPT
LOOP bottle=1,100
SET bottlenr=100-bottle
IF (bottlenr==0) THEN
PRINT "no bottle of beer on the wall"
EXIT
ELSEIF (bottlenr==1) THEN
PRINT bottlenr, " bottle of beer on the wall"
PRINT bottlenr, " bottle of beer"
ELSE
PRINT bottlenr, " bottles of beer on the wall"
PRINT bottlenr, " bottles of beer"
ENDIF
PRINT "Take one down, pass it around"
ENDLOOP
 

[edit] TXR

The (range 99 -1 -1) expression produces a lazy list of integers from 99 down to -1. The mapcar* function lazily maps these numbers to strings, and the rest of the code treats this lazy list as text stream to process, extracting the numbers with some pattern matching cases and interpolating them into the song's text. Functional programming with lazy semantics meets text processing, pattern matching and here documents.

@(next :list @(mapcar* (fun tostring) (range 99 -1 -1)))
@(collect)
@number
@ (trailer)
@number_less_1
@ (cases)
@ (bind number "1")
@ (output)
1 bottle of beer one the wall
1 bottle of beer
@ (end)
@ (or)
@ (output)
@number bottles of beer one the wall
@number bottles of beer
@ (end)
@ (end)
@ (cases)
@ (bind number "0")
@ (output)
Go to the store and get some more,
99 bottles of beer on the wall!
 
@ (end)
@ (or)
@ (output)
Take one down and pass it around
@number_less_1 bottles of beer on the wall
 
@ (end)
@ (end)
@(end)

To make the song repeat indefinitely, change the first line to:

@(next :list @(mapcar* (fun tostring) (repeat (range 99 0 -1))))

Now it's processing an infinite lazy lists consisting of repetitions of the integer sequences 99 98 ... 0.

[edit] UNIX Shell

See 99 Bottles of Beer/Shell

[edit] UnixPipes

See 99 Bottles of Beer/Shell

[edit] Ursala

#import nat
 
# each function takes a natural number to a block of text
 
quantity = # forms the plural as needed
 
~&iNC+ --' of beer'+ ~&?(
1?=/'1 bottle'! --' bottles'+ ~&h+ %nP,
'no more bottles'!)
 
verse =
 
^(successor,~&); ("s","n"). -[
-[quantity "s"]- on the wall, -[quantity "s"]-,
Take one down and pass it around, -[quantity "n"]- on the wall.]-
 
refrain "n" =
 
-[
No more bottles of beer on the wall, -[quantity 0]-.
Go to the store and buy some more, -[quantity "n"]- on the wall.]-
 
whole_song "n" = ~&ittt2BSSL (verse*x iota "n")--<refrain "n">
 
#show+
 
main = whole_song 99

[edit] V

[bottles
[newline <nowiki>''</nowiki> puts].
[beer
[0 =] ['No more bottles of beer' put] if
[1 =] ['One bottle of beer' put] if
[1 >] [dup put ' bottles of beer' put] if].
[0 =] [newline]
[beer ' on the wall, ' put beer newline
'Take one down and pass it around, ' put pred beer ' on the wall' puts newline]
tailrec].
 
99 bottles

[edit] Vala

void main() {
uint bottles = 99;
do {
print("%u bottles of beer on the wall.\n", bottles);
print("%u bottles of beer!\n", bottles);
print("Take one down, pass it around!\n");
--bottles;
if (bottles == 0) {
print("No bottles");
}
else if (bottles == 1) {
print("1 bottle");
}
else {
print("%u bottles", bottles);
}
print(" of beer on the wall!\n\n");
} while (bottles != 0);
}

[edit] VBA

See 99 Bottles of Beer/Basic

[edit] VBScript

See 99 Bottles of Beer/Basic

[edit] Visual Prolog

See 99 Bottles of Beer/Prolog

[edit] Vox

 
// translated from <http://rosettacode.org/wiki/99_Bottles_of_Beer#JavaScript>
 
local beer;
while((beer = typeof beer == "null" ? 99 : beer) > 0)
println(
beer + " bottle" +
(beer != 1 ? "s" : "") +
" of beer on the wall\n" + beer + " bottle" +
(beer != 1 ? "s" : "") +
" of beer\nTake one down, pass it around\n" +
(--beer) + " bottle" +
(beer != 1 ? "s" : "") + " of beer on the wall\n"
);
 

[edit] Wart

See 99 Bottles of Beer/Lisp

[edit] Whenever

See 99 Bottles of Beer/EsoLang

[edit] Wortel

!console.log @unlines ~!* 99..0 !? {
0 "0 bottles of beer on the wall\n0 bottles of beer\nbetter go to the store and buy some more."
"{@x} bottle{@?@x{1 @e 's}} of beer on the wall\n{@x} bottle{@?@x{1 @e 's}} of beer\nTake one down, pass it around"
}

[edit] Wrapl

MOD Bottles;
 
IMP IO.Terminal USE Out;
IMP Std.String;
 
VAR i, s <- "s", ob <- "of beer", otw <- "on the wall",
more <- "Take one down and pass it around", verse <- [];
 
EVERY i <- 99:to(0,-1) DO (
(i = 1) & (s <- "");
(i = 0) & (s <- "s"; i <- "No more"; more <- "Go to the store and buy some more");
verse:put('. {i} bottle{s} {ob} {otw}.\n');
verse:put('\n{i} bottle{s} {ob} {otw}, {([email protected]):lower} bottle{s} {ob}.\n{more}');
);
 
Out:write(verse[2,0]@(String.T, "") + verse[1]);
 
END Bottles.

[edit] X86 Assembly

See 99 Bottles of Beer/Assembly

[edit] XPL0

code IntOut=11, Text=12;
int B;
[B:= 99;
repeat IntOut(0, B); Text(0, " bottles of beer on the wall^M^J");
IntOut(0, B); Text(0, " bottles of beer^M^J");
Text(0, "Take one down, pass it around^M^J");
B:= B-1;
IntOut(0, B); Text(0, " bottles of beer on the wall^M^J^J");
until B=0;
]

[edit] Yorick

[edit] Looped version

bottles = 99;
while(bottles) {
write, format=" %d bottles of beer on the wall\n", bottles;
write, format=" %d bottles of beer\n", bottles;
write, "Take one down, pass it around";
write, format=" %d bottles of beer on the wall\n\n", --bottles;
}

[edit] Vectorized version

song = "%d bottles of beer on the wall\n";
song += "%d bottles of beer\n";
song += "Take one down, pass it around\n";
song += "%d bottles of beer on the wall\n";
beer = indgen(99:1:-1);
write, format=song, beer, beer, beer-1;


[edit] Z80 Assembly

See 99 Bottles of Beer/Assembly

[edit] zkl

[99..0,-1].pump(fcn(n){
println(beers(n), " on the wall, ", beers(n).toLower(), ".\n",
n==0 and ("Go to the store and buy some more, 99 bottles of beer") or
("Take one down and pass it around, " + beers(n-1).toLower()),
" on the wall.\n")
});
fcn beers(n){
(n==0 and "No more bottles" or (n==1 and "1 bottle" or "" + n + " bottles"))
+ " of beer"
}
Output:
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.
...
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.

No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox