99 Bottles of Beer

From Rosetta Code

Jump to: navigation, search
99 Bottles of Beer a programming puzzle. It lays out a problem which Rosetta Code users are encouraged to solve, using languages and techniques they know. Multiple approaches are not discouraged, so long as the puzzle guidelines are followed. For other Puzzles, see Category:Puzzles.
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: http://99-bottles-of-beer.net/

Contents

[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] 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] 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] 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] 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] AutoHotkey

; RC: 99 bottles of beer
b = 99
Loop, %b% {
s .= 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`n"
b--
}
Gui, Add, Edit, w200 h200, %s%
Gui, Show, , 99 bottles of beer
Return ; end of auto-execute section
 
GuiClose:
ExitApp
Return

Delayed Sing along

n=99
Gui, Font, s20 cMaroon, Comic Sans MS
Gui, Add, Text, w500 vLyrics, %n% bottles of beer on the wall...
Gui, Show
Loop {
Sleep, 2000
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer.":n " bottle of beer."
Sleep, 2000
GuiControl,,Lyrics,% n ? "Take one down, pass it around...":"Go to the store, buy some more..."
Sleep, 2000
n := n ? --n:99
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall.":n " bottle of beer on the wall."
Sleep, 2000
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall...":n " bottle of beer on the wall..."
}
GuiClose:
ExitApp

Fast and Short

b=99
Loop, %b% {
s := b " bottles of beer on the wall, " b "bottles of beer, Take one down, pass it around " b-1 " bottles of beer on the wall"
b--
TrayTip,,%s%
sleep, 40
}

[edit] AWK

{ 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--
print i, " bottles of beer on the wall\n"}}

[edit] Batch File

@echo off
setlocal
:main
for /L %%i in (99,-1,1) do (
call :verse %%i
)
echo no bottles of beer on the wall
echo no bottles of beer
echo go to the store and buy some more
echo 99 bottles of beer on the wall
echo.
set /p q="Keep drinking? "
if %q% == y goto main
if %q% == Y goto main
goto :eof
 
:verse
call :plural %1 res
echo %res% of beer on the wall
echo %res% of beer
call :oneit %1 res
echo take %res% down and pass it round
set /a c=%1-1
call :plural %c% res
echo %res% of beer on the wall
echo.
goto :eof
 
:plural
if %1 gtr 1 goto :gtr
if %1 equ 1 goto :equ
set %2=no bottles
goto :eof
:gtr
set %2=%1 bottles
goto :eof
:equ
set %2=1 bottle
goto :eof
 
:oneit
if %1 equ 1 (
set %2=it
) else (
set %2=one
)
goto :eof

[edit] BASIC

Works with: QuickBasic version 4.5

[edit] Sound

This version plays the tune 100 times while printing out the lyrics (not synchronized).

PLAY "<"
FOR x = 99 TO 0 STEP -1
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
PLAY "e-8e-8e-8<b-8b-8b-8>e-8e-8e-8e-4"'X bottles of beer on the wall
PLAY "f8f8f8c8c8c8f4"'X bottles of beer
PLAY "d4d8d8 N0 d8d8d8d4"'take one down, pass it around
PLAY "<a+8a+8a+8>c8c8d8d+8d+8d+8d+4"'X-1 bottles of beer on the wall
NEXT x

[edit] Text

FOR x = 99 TO 1 STEP -1
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
NEXT x

[edit] Befunge

This outputs a single CR (ASCII code 13) between verses; this needs changing for systems other than DOS, Windows, and Mac OS.

<v  <.g10" bottles of beer on the wall"+*4310     <
c>:,|
<v <.g10" bottles of beer"+*4310
>:,|
<v <"take one down, pass it around"+*4310
>:,|
>01g1-:01p v
v <.g10" bottles of beer on the wall"+*4310<
>:,|
>134*+0` |
@

[edit] Brainf***

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

[edit] C

Translation of: C++

[edit] The simple solution

#include <stdio.h>
int main() {
int bottles = 99;
do {
printf("%d bottles of beer on the wall\n", bottles);
printf("%d bottles of beer\n", bottles);
printf("Take one down, pass it around\n");
printf("%d bottles of beer on the wall\n\n", --bottles);
} while( bottles > 0 );
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 <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()
{
printf(SONG);
return 0;
}

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

[edit] C++

[edit] The simple solution

#include <iostream>
using namespace std;
 
int main()
{
int bottles = 99;
do {
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;
} while (bottles > 0);
}

[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] 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 new {
Word=(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.Word);
}
}
}

[edit] Chef

 
 
99 Bottles Of Beer.
 
Ingredients.
99 bottles
 
Method.
Loop the bottles.
Put bottles into 1st mixing bowl.
Serve with bottles of beer on the wall.
Clean 1st mixing bowl.
Put bottles into 1st mixing bowl.
Serve with bottles of beer.
Clean 1st mixing bowl.
Serve with Take one down and pass it around.
Clean 1st mixing bowl.
Loop the bottles until looped.
Serve with No more bottles of beer.
Clean 1st mixing bowl.
Pour contents of the 3rd mixing bowl into the 1st baking dish.
 
Serves 1.
 
bottles of beer on the wall.
 
Prints out "n" bottles of beer on the wall.
 
Ingredients.
108 g lime
97 cups asparagus
119 pinches watercress
32 tablespoons pickles
101 pinches eggplant
104 g huckleberry
116 teaspoons turnip
110 tablespoons nannyberry
111 tablespoons onion
114 tablespoons raspberry
98 g broccoli
102 g feijoa
115 teaspoons squach
10 ml new line
 
Method.
Put new line into 1st mixing bowl.
Put lime into 2nd mixing bowl.
Put lime into 2nd mixing bowl.
Put asparagus into 2nd mixing bowl.
Put watercress into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put huckleberry into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put nannyberry into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put raspberry into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put broccoli into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put feijoa into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put squach into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put lime into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put broccoli into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Liquify contents of the 2nd mixing bowl.
Pour contents of the 2nd mixing bowl into the baking dish.
Pour contents of the mixing bowl into the baking dish.
Refrigerate for 1 hour.
 
bottles of beer.
 
Prints out "n" bottles of beer.
 
Ingredients.
114 tablespoons raspberry
101 pinches eggplant
98 teaspoons broccoli
32 pinches pickles
102 tablespoons feijoa
111 teaspoons onion
115 cups squach
108 cups lime
116 teaspoons turnip
10 ml new line
 
Method.
Put new line into 1st mixing bowl.
Put raspberry into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put broccoli into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put feijoa into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put squach into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put lime into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put broccoli into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Liquify contents of the 2nd mixing bowl.
Pour contents of the 2nd mixing bowl into the baking dish.
Pour contents of the mixing bowl into the baking dish.
Refrigerate for 1 hour.
 
 
Take one down and pass it around.
 
Prints out "Take one down and pass it around".
 
Ingredients.
100 cups dandelion
110 g nannyberry
117 pinches cucumber
111 pinches onion
114 pinches raspberry
97 g asparagus
32 tablespoons pickles
116 pinches turnip
105 g chestnut
115 g squach
112 g pumpkin
119 cups watercress
101 g eggplant
107 g kale
84 cups tomatoe
10 ml new line
 
Method.
Put new line into 3rd mixing bowl.
Put dandelion into 2nd mixing bowl.
Put nannyberry into 2nd mixing bowl.
Put cucumber into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put raspberry into 2nd mixing bowl.
Put asparagus into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put chestnut into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put squach into 2nd mixing bowl.
Put squach into 2nd mixing bowl.
Put asparagus into 2nd mixing bowl.
Put pumpkin into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put dandelion into 2nd mixing bowl.
Put nannyberry into 2nd mixing bowl.
Put asparagus into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put nannyberry into 2nd mixing bowl.
Put watercress into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put dandelion into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put nannyberry into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put kale into 2nd mixing bowl.
Put asparagus into 2nd mixing bowl.
Put tomatoe into 2nd mixing bowl.
Liquify contents of the 2nd mixing bowl.
Pour contents of the 2nd mixing bowl into the baking dish.
Pour contents of the 3rd mixing bowl into the baking dish.
Refrigerate for 1 hour.
 
No more bottles of beer.
 
Prints out "No more bottles of beer".
 
Ingredients.
114 pinches raspberry
101 teaspoons eggplant
98 cups broccoli
32 tablespoons pickles
102 pinches feijoa
111 cups onion
115 tablespoons squach
108 tablespoons lime
116 pinches turnip
109 cups mushrooms
78 g nectarine
10 ml new line
 
Method.
Put new line into 3rd mixing bowl.
Put new line into 2nd mixing bowl.
Put raspberry into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put broccoli into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put feijoa into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put squach into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put lime into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put turnip into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put broccoli into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put eggplant into 2nd mixing bowl.
Put raspberry into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put mushrooms into 2nd mixing bowl.
Put pickles into 2nd mixing bowl.
Put onion into 2nd mixing bowl.
Put nectarine into 2nd mixing bowl.
Liquify contents of the 2nd mixing bowl.
Pour contents of the 2nd mixing bowl into the baking dish.
Pour contents of the 3rd mixing bowl into the baking dish.
Refrigerate for 1 hour.
 
 

[edit] Clips

From http://mail.99-bottles-of-beer.net/language-clips-130.html

 
;Written by Bill Ensinger (Bill222E@aol.com) on Saturday February 24, 1996
;8:00 - 9:41 pm Eastern Standard time at Taylor University.
;All praise to God; note that we just pass the beer, but don't drink!
 
(deftemplate beer
(field ninetynine))
 
(deffacts bottles
(beer (ninetynine 99)))
 
 
(defrule Bottlesninetynine ""
(beer (ninetynine ?bottlenum))
 ?fl <- (beer (ninetynine ?bottlenum))
(test (> ?bottlenum 2))
=>
(printout t ?bottlenum " bottles of beer on the wall," t)
(printout t ?bottlenum " bottles of beer." t)
(printout t "Take one down, pass it around," t)
(printout t (- ?bottlenum 1) " bottles of beer on the wall." t)
(printout t " " t)
(modify ?fl (ninetynine =(- ?bottlenum 1)))
)
(defrule Bottlestwo ""
(beer (ninetynine 2))
 ?fl <- (beer (ninetynine ?bottlenum))
=>
(printout t ?bottlenum " bottles of beer on the wall," t)
(printout t ?bottlenum " bottles of beer." t)
(printout t "Take one down, pass it around," t)
(printout t (- ?bottlenum 1) " bottle of beer on the wall." t)
(printout t " " t)
(modify ?fl (ninetynine =(- ?bottlenum 1)))
)
 
(defrule Bottlesone ""
(beer (ninetynine 1))
 ?fl <- (beer (ninetynine ?bottlenum))
=>
(printout t ?bottlenum " bottle of beer on the wall," t)
(printout t ?bottlenum " bottle of beer." t)
(printout t "Take one down, pass it around," t)
(printout t "No more bottles of beer on the wall!" t)
)
 


[edit] Clojure

(defn verse [n]
(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)))
 
(defn sing [start]
(dorun (map verse (range start 0 -1))))


[edit] Common Lisp

(defun bottles (x)
(loop for bottles from x downto 1
do (format t "~a bottle~:p of beer on the wall
~:*~a bottle~:p of beer
Take one down, pass it around
~a bottle~:p of beer on the wall~2%"
bottles (1- bottles))))

and then just call

(bottles 99)

[edit] D

Uses a non-commutative operator to construct a narrative expression of 99-bottles song.

module nbottles ;
import std.string ;
import std.stdio ;
 
alias Exception NoMoreBottlesLeft ;
 
enum { // role
None = 0x0, // normal for OP and Term
Taker = 0x1, // for OP that minus one bottlesLeft
Viewer = 0x2, // for Term display bottlesLeft
NewLine = 0x4, // for Term that sending a newline to IO
}
class XP {
static string[] ones = ["","one","two","three","four",
"five","six","seven","eight","nine"] ;
static string[] tens = ["", "ten", "twenty","thirty","fourty",
"fifty","sixty","seventy","eighty","ninty"] ;
static string[] teens = ["","eleven","twelve","thirteen","fourteen",
"fifteen","sixteen","seventeen","eighteen","nineteen"] ;
static private int bottlesLeft = 99 ;
static bool opCall() {
if (bottlesLeft == 0)
throw new NoMoreBottlesLeft("") ;
return true ;
}
static string Cap(string s) {
return toupper(s[0..1]) ~ s[1..$] ;
}
static string num2word(int i) {
if (i == 0)
return "No more" ;
//return std.string.toString(i) ;
string[2] digits ;
int numTen = i / 10 ;
int numOne = i % 10 ;
if(i == 10)
digits[1] = tens[1] ;
else if(numTen == 0)
digits[1] = ones[numOne] ;
else if(numTen == 1)
digits[1] = teens[numOne] ;
else {
digits[0] = tens[numTen] ;
digits[1] = ones[numOne] ;
}
return Cap(strip(join(digits," "))) ;
}
static string getBottles() {
string num = num2word(bottlesLeft) ;
string pural = (bottlesLeft != 1) ? "s" : "";
return num ~ " bottle" ~ pural ;
}
string words ;
int role ;
this (string w, int r) { words = w, role = r ; }
string getWord() {
string postfix = " ";
string word ;
if (words is null)
return "" ;
else
word = words ;
if (role & Viewer)
word = getBottles ;
if (role & NewLine)
postfix = "\n" ;
return word ~ postfix ;
}
}
alias XP A_drunker_sings_a_song ;
 
class Term : XP {
this (string w = null, int r = None) { super(w, r) ; }
}
class OP : XP {
this (string w = null, int r = None) { super(w, r) ; }
OP opDiv_r(Term t) {
if(role & Taker)
A_drunker_sings_a_song.bottlesLeft-- ;
writef(t.getWord) ;
writef(getWord) ;
return this ;
}
Term opDiv(Term t) {
writef(t.getWord) ;
return new Term ;
}
}
 
void main() {
Term N_bottles = new Term("", Viewer) ;
OP of = new OP("of") ;
Term beer = new Term("beer") ;
OP on = new OP("on") ;
Term the_wall = new Term("the wall", NewLine) ;
Term beer_ = new Term("beer", NewLine) ;
Term Take = new Term("Take") ;
OP one = new OP("one", Taker) ;
Term down = new Term("down,") ;
Term pass = new Term("pass") ;
OP it = new OP("it") ;
Term around = new Term("around", NewLine) ;
Term the_wall_ = new Term("the wall\n", NewLine) ;
 
try{
for(; A_drunker_sings_a_song();
 
N_bottles/of/beer/on/the_wall,
N_bottles/of/beer_ ,
Take/one/down, pass/it/around,
N_bottles/of/beer/on/the_wall_
 
) {}
} catch (NoMoreBottlesLeft e) {
writefln("Go buy more beer!") ;
}
 
}

A more practical implementation can be found on: 99-bottles-of-beer.net

[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] 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] 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

[$." bottle"$1-["s"]?" of beer"]b:
99
[$][b;!" on the wall
"b;!"
Take one down and pass it around
"1-b;!" on the wall
"]#%

[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] 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] 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] Go

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

[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] 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] 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] 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

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

[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+

9

[edit] Icon and Unicon

[edit] Icon

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] Unicon

This Icon solution works in Unicon. A solution that uses Unicon extensions has not been provided.

[edit] Intercal

See 99 Bottles of Beer/Intercal

[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

[edit] Java

[edit] Console

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

import java.text.MessageFormat;
public class Beer{
static String bottles(int n){
return MessageFormat.format("{0,choice,0#No more bottles|1#One bottle|2#{0} bottles} of beer", n);
}
public static void main(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");
}
}
}

[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] 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.dfanning.com/tips/forloops.html and http://www.dfanning.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] JavaScript

[edit] The simple solution

// Line breaks are in HTML
var beer = 99;
while ( beer > 0)
{
document.write( beer + " bottles of beer on the wall<br>" );
document.write( beer + " bottles of beer<br>" );
document.write( "Take one down, pass it around<br>" );
document.write( ( beer - 1 ) + " bottles of beer on the wall<br>" );
beer--;
}

[edit] More skilled solution "one-liner" with grammar check

// Line breaks are in HTML
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>" );
 

[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] 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] Logo

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] 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

[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] Mathematica

texts = ToString[#] <> " bottles of beer on the wall\n" <> ToString[#] <> 
" bottles of beer\nTake one down and pass it around\n" <>
ToString[# - 1] <> " bottles of beer on the wall" & /@ Range[99, 1, -1];
AppendTo[texts, "No more bottles of beer on the wall, no more bottles of beer\nGo \
to the store and buy some more, 99 bottles of beer on the wall"];
texts = StringJoin@Riffle[texts, "\n\n"];
Print@StringReplace[texts, "\n1 bottles" -> "\n1 bottle"]

[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] 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] Make

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

[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] MPIF90

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] 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] NewLISP

 
(for (n 99 1)
(println n " bottles of beer on the wall," n " bottles of beer. Take one down, pass it around. ")
(println (- n 1) "bottles of beer on the wall!"))
 
 
;;recursive
;;also shows list afterword
(define (rec bottles)
(if (!= 0 bottles) (print "/n" bottles " bottles of beer on the wall" bottles " bottles of beer.
\nTake one down, pass it around, "
(- bottles 1)
" bottles of beer on the wall" (rec ( - bottles 1))))(list bottles))
 
 
(rec 99)
 

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

[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 x = match x with
| 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 n = match n with
| 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] 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] 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] Pascal

procedure BottlesOfBeer;
var
i: Integer;
begin
for i := 99 downto 1 do
begin
if i = 1 then
begin
WriteLn('1 bottle of beer on the wall');
WriteLn('1 bottle of beer');
WriteLn('Take one down, pass it around');
WriteLn('No more bottles of beer on the wall');
Exit;
end;
WriteLn(Format('%d bottles of beer on the wall', [i]));
WriteLn(Format('%d bottles of beer', [i]));
WriteLn('Take one down, pass it around');
WriteLn(Format('%d bottles of beer on the wall', [Pred(i)]));
WriteLn('');
end;
end;

[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;
}

[edit] Perl 6

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] 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";
}
?>

Alternatively:

<?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] PicoLisp

(de bottles (N)
(case N
(0 "No more beer")
(1 "One bottle of beer")
(T (cons N " bottles of beer")) ) )
 
(for (N 99 (gt0 N))
(prinl (bottles N) " on the wall,")
(prinl (bottles N) ".")
(prinl "Take one down, pass it around,")
(prinl (bottles (dec 'N)) " on the wall.")
(prinl) )

[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");
}

[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

\obeylines
\newtoks\bottle \bottle={bottle}
\newtoks\ofbeer \ofbeer={of beer}
\newtoks\onthewall \onthewall={on the wall}
\newtoks\passit \passit={Take one down, pass it around}
\def\song#1{#1 \the\bottle\ifnum#1>1\relax s\fi%
\ \the\ofbeer\ \the\onthewall
#1 \the\bottle\ifnum#1>1\relax s\fi\ \the\ofbeer
\the\passit}
\newcount\bottles \bottles99
\loop\song{\number\bottles}
\advance\bottles-1\ifnum\bottles>1\repeat
0 \the\bottle s \the\ofbeer\ \the\onthewall
\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] PowerShell

A standard impementation using a For loop

 
for($n=99; $n -gt 0; $n--) {
"$n bottles of beer on the wall"
"$n bottles of beer"
"Take one down, pass it around"
[string]($n-1) + " bottles of beer on the wall"
""
}
 

Consolidating the static text and using a Do loop

 
$n=99
do {
"{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n" -f $n, --$n
} while ($n -gt 0)
 

Consolidating the static text even more

 
$s = "{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n"
$n=99
do { $s -f $n, --$n } while ($n -gt 0)
 

[edit] Prolog

Works with: SWI Prolog

 
bottles(0):-!.
bottles(X):-
writef('%t bottles of beer on the wall \n',[X]),
writef('%t bottles of beer\n',[X]),
write('Take one down, pass it around\n'),
succ(XN,X),
writef('%t bottles of beer on the wall \n\n',[XN]),
bottles(XN).
 
:- bottles(99).
 

An other version that handles plural/not plural conditions.

 
line2(0):- write('no more bottles of beer').
line2(1):- write('1 bottle of beer').
line2(X):- writef('%t bottles of beer',[X]).
line1_4(X):- line2(X),write(' on the wall').
line3(1):- write('Take it down, pass it around').
line3(X):- write('Take one down, pass it around').
 
verse(X):-
line1_4(X),write('\n'),
line2(X),write('\n'),
line3(X),write('\n'),
succ(N,X),
line1_4(N),write('\n'),
write('\n').
 
bottles(0):-!.
bottles(X):-
verse(X),
succ(XN,X),
bottles(XN).
 
:- bottles(99).
 

[edit] PureBasic

If OpenConsole()
Define Bottles=99
While Bottles
PrintN(Str(Bottles)+" bottles of beer on the wall")
PrintN(Str(Bottles)+" bottles of beer")
PrintN("Take one down, pass it around")
Bottles-1
PrintN(Str(Bottles)+" bottles of beer on the wall"+#CRLF$)
Wend
 
PrintN(#CRLF$+#CRLF$+"Press ENTER to exit"):Input()
CloseConsole()
EndIf

[edit] Python

[edit] Normal Code

for bottles in range(99,0,-1):
print bottles, "bottles of beer on the wall"
print bottles, "bottles of beer"
print "Take one down, pass it around"
print bottles-1, "bottles of beer on the wall"

[edit] Using a template

verse = '''\
%i bottles of beer on the wall
%i bottles of beer
Take one down, pass it around
%i bottles of beer on the wall
'
''
 
for bottles in range(99,0,-1):
print verse % (bottles, bottles, bottles-1)
 

[edit] New-style template (Python 2.6)

verse = '''\
{some} bottles of beer on the wall
{some} bottles of beer
Take one down, pass it around
{less} bottles of beer on the wall
'
''
 
for bottles in range(99,0,-1):
print verse.format(some=bottles, less=bottles-1)
 

[edit] "Clever" list comprehension

a, b, c, s = " bottles of beer", " on the wall\n", "Take one down, pass it around\n", str
print "\n".join([s(x)+a+b+s(x)+a+"\n"+c+s(x-1)+a+b for x in xrange(99, 0, -1)])

[edit] A wordy version

ones = (
'', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'
)
prefixes = ('thir', 'four', 'fif', 'six', 'seven', 'eigh', 'nine')
tens = ['', '', 'twenty' ]
teens = ['ten', 'eleven', 'twelve']
for prefix in prefixes:
tens.append(prefix + 'ty')
teens.append(prefix +'teen')
tens[4] = 'forty'
 
def number(num):
"get the wordy version of a number"
ten, one = divmod(num, 10)
if ten == 0 and one == 0:
return 'no'
elif ten == 0:
return ones[one]
elif ten == 1:
return teens[one]
elif one == 0:
return tens[ten]
else:
return "%s-%s" % (tens[ten], ones[one])
 
def bottles(beer):
"our rephrase"
return "%s bottle%s of beer" % (
number(beer).capitalize(), 's' if beer > 1 else ''
)
 
onthewall = 'on the wall'
takeonedown = 'Take one down, pass it around'
for beer in range(99, 0, -1):
print bottles(beer), onthewall
print bottles(beer)
print takeonedown
print bottles(beer-1), onthewall
print

[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

bottleofbeer <- function(n) {
v <- 1
for (b in n:0) {
cat(b, " bottle",
ifelse(b!=1, "s", ""),
" of beer on the wall\n",
b, " bottle", ifelse(b!=1, "s", ""), " of beer\n",
"Take one down, pass it around\n", sep="")
}
}
 
bottleofbeer(99)

[edit] REALbasic

Place the following in the "open" event of a console application.

 
dim bottles as Integer = 99
While bottles > 0
stdout.writeline(str(bottles) + " bottles of beer on the wall")
stdout.writeline(str(bottles) + " bottles of beer")
stdout.writeline("Take one down, pass it around")
bottles = bottles - 1
stdout.writeline(str(bottles) + " bottles of beer on the wall")
Wend
 

[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

[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
 

[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] 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] 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

   /=!/===========!/==+++++++++#   +9
| | /=!/=====@/==@@@+@+++++# +48 (itoa)
| | | | /==!/==@@@@=++++# +32 (space)
| | | | | \==@@++\!+++++++++++++\!+++++\
9 9 '9 9' space 'b' 'o' 't'
$@/>@/>@/>@/>@/>========@/>============@/>====@/>++++++++++ \n setup
/====================================loop=====>\!=>\!<<<<<<<< /
\@\@\>cr.@\< ?\<->+++++++++>->+++++++++\ | |
 ! | | \===-========>=>-==BCD==!\< @\< ?/< ?/# no more beer!
/=|=====|================================/
| | \<++t.<<----a.>----k.<++++e.<_.>>++++o.-n.< e.<_.>-d.>+o.>+++w.<-n.<<_.\
| | / /
| | \>---a.>n.<+++d.<_.>>++p.<---a.>>----s.s.<<<_.>>-------i.>+t.<<<_.\
| | / /
| | \>a.>>--r.<++++++o.>+++u.<-n.<+++d.>>>cr.<-T<+O<--B<<<#
| !
\@\<<<_.>>o.-n.<<_.>>>++t.<<+++h.---e.<_.>>>+++w.<<----a.>--l.l.>>CR.<---T<+++O<+B<<<#
|
\9.>9.>_.>B.>O.>T.t.<---l.<+++e.>>-s.<<<_.>>+++O.<+f.<_.>----b.+++e.E.>>-R.#

[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] Tcl

set s "s"; set ob "of beer"; set otw "on the wall"; set more "Take one down and pass it around"
for {set n 100} {$n ne "No more"} {} {
switch -- [incr n -1] {
1 {set s ""}
0 {set s "s"; set n "No more"; set more "Go to the store and buy some more"}
}
lappend verse ". $n bottle$s $ob $otw.\n"
lappend verse "\n$n bottle$s $ob $otw, [string tolower $n] bottle$s $ob.\n$more"
}
puts -nonewline [join [lreplace $verse 0 0] ""][lindex $verse 0]

See also 99 Bottles of Beer/Tcl

[edit] TI-89 BASIC

Prgm
Local i,plural,clockWas,t,k,wait
"s" → plural
0 → k
isClkOn() → clockWas
 
Define wait() = Prgm
EndPrgm
 
ClockOn
 
For i,99,0,–1
Disp ""
Disp string(i) & " bottle" & plural & " of beer on the"
Disp "wall, " & string(i) & " bottle" & plural & " of beer."
 
getTime()[3]→t
While getTime()[3] = t and k = 0 : getKey() → k : EndWhile
If k ≠ 0 Then : Exit : EndIf
 
Disp "Take one down, pass it"
Disp "around."
 
getTime()[3]→t
While getTime()[3] = t and k = 0 : getKey() → k : EndWhile
If k ≠ 0 Then : Exit : EndIf
 
If i - 1 = 1 Then
"" → plural
EndIf
If i > 1 Then
Disp string(i-1) & " bottle" & plural & " of beer on the"
Disp "wall."
Else
Disp "No more bottles of beer on"
Disp "the wall."
EndIf
 
getTime()[3]→t
While abs(getTime()[3] - t)<2 and k = 0 : getKey() → k : EndWhile
If k ≠ 0 Then : Exit : EndIf
 
EndFor
If not clockWas Then
ClockOff
ENdIf
EndPrgm

[edit] UnixPipes

  1. Unix Pipes, avoiding all the turing complete sub programs like sed, awk,dc etc.
mkdir 99 || exit 1
trap "rm -rf 99" 1 2 3 4 5 6 7 8
 
(cd 99
mkfifo p.b1 p.b2 p.verse1 p.wall p.take
yes "on the wall" > p.wall &
yes "Take one down and pass it around, " > p.take &
(yes "bottles of beer" | nl -s\ | head -n 99 | tac | head -n 98 ;
echo "One bottle of beer";
echo "No more bottles of beer") | tee p.b1 p.b2 |
paste -d"\ " - p.wall p.b1 p.take | head -n 99 > p.verse1 &
cat p.b2 | tail -99 | paste -d"\ " p.verse1 - p.wall | head -n 99
)
rm -rf 99

[edit] UNIX Shell

Works with: Bourne Again SHell

#! /bin/bash
 
for((i=99; i >= 0; i--)); do
if [[ $i -gt 1 ]] || [[ $i -eq 0 ]]; then
s="s"
else
s=""
fi
echo "$i bottle$s of beer on the wall"
if [[ $i -ne 0 ]]; then
echo "$i bottle$s of beer
Take one down, pass it around"

fi
done

[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] VBScript

[edit] Simple Method

sub song( numBottles )
dim i
for i = numBottles to 0 step -1
if i > 0 then
wscript.echo pluralBottles(i) & " of beer on the wall"
wscript.echo pluralBottles(i) & " of beer"
if i = 1 then
wscript.echo "take it down"
else
wscript.echo "take one down"
end if
wscript.echo "and pass it round"
wscript.echo pluralBottles(i-1) & " of beer on the wall"
wscript.echo
else
wscript.echo "no more bottles of beer on the wall"
wscript.echo "no more bottles of beer"
wscript.echo "go to the store"
wscript.echo "and buy some more"
wscript.echo pluralBottles(numBottles) & " of beer on the wall"
wscript.echo
end if
next
end sub
 
function pluralBottles( n )
select case n
case 1
pluralBottles = "one bottle"
case 0
pluralBottles = "no more bottles"
case else
pluralBottles = n & " bottles"
end select
end function
 
song 3

Outputs:

 
3 bottles of beer on the wall
3 bottles of beer
take one down
and pass it round
2 bottles of beer on the wall
 
2 bottles of beer on the wall
2 bottles of beer
take one down
and pass it round
one bottle of beer on the wall
 
one bottle of beer on the wall
one bottle of beer
take it down
and pass it round
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
3 bottles of beer on the wall

[edit] Regular Expressions and Embedded Scripting

Another way of doing it, using Regular Expressions to locate executable code inside {} and replacing the code with the result of its evaluation.

function pluralBottles( n )
select case n
case 1
pluralBottles = "one bottle"
case 0
pluralBottles = "no more bottles"
case else
pluralBottles = n & " bottles"
end select
end function
 
function eef( b, r1, r2 )
if b then
eef = r1
else
eef = r2
end if
end function
 
Function evalEmbedded(sInput, sP1)
dim oRe, oMatch, oMatches
dim sExpr, sResult
Set oRe = New RegExp
'Look for expressions as enclosed in braces
oRe.Pattern = "{(.+?)}"
sResult = sInput
do
Set oMatches = oRe.Execute(sResult)
if oMatches.count = 0 then exit do
for each oMatch in oMatches
'~ wscript.echo oMatch.Value
for j = 0 to omatch.submatches.count - 1
sExpr = omatch.submatches(j)
sResult = Replace( sResult, "{" & sExpr & "}", eval(sExpr) )
next
next
loop
evalEmbedded = sResult
End Function
 
sub sing( numBottles )
dim i
for i = numBottles to 0 step -1
if i = 0 then
wscript.echo evalEmbedded("no more bottles of beer on the wall" & vbNewline & _
"no more bottles of beer" & vbNewline & _
"go to the store and buy some more" & vbNewline & _
"{pluralBottles(sP1)} of beer on the wall" & vbNewline, numBottles)
else
wscript.echo evalEmbedded("{pluralBottles(sP1)} of beer on the wall" & vbNewline & _
"{pluralBottles(sP1)} of beer" & vbNewline & _
"take {eef(sP1=1,""it"",""one"")} down and pass it round" & vbNewline & _
"{pluralBottles(sP1-1)} of beer on the wall" & vbNewline, i)
end if
next
end sub
 
sing 3

[edit] Visual Basic

Sub Main()
Const bottlesofbeer As String = " bottles of beer"
Const onthewall As String = " on the wall"
Const takeonedown As String = "Take one down, pass it around"
Const onebeer As String = "1 bottle of beer"
 
Dim bottles As Long
 
For bottles = 99 To 3 Step -1
Debug.Print CStr(bottles) & bottlesofbeer & onthewall
Debug.Print CStr(bottles) & bottlesofbeer
Debug.Print takeonedown
Debug.Print CStr(bottles - 1) & bottlesofbeer & onthewall
Debug.Print
Next
 
Debug.Print "2" & bottlesofbeer & onthewall
Debug.Print "2" & bottlesofbeer
Debug.Print takeonedown
Debug.Print onebeer & onthewall
Debug.Print
 
Debug.Print onebeer & onthewall
Debug.Print onebeer
Debug.Print takeonedown
Debug.Print "No more" & bottlesofbeer & onthewall
Debug.Print
 
Debug.Print "No" & bottlesofbeer & onthewall
Debug.Print "No" & bottlesofbeer
Debug.Print "Go to the store, buy some more"
Debug.Print "99" & bottlesofbeer & onthewall
End Sub

[edit] Visual Basic .NET

Platform: .NET

Module Module1
Sub Main()
Dim Bottles As Integer
For Bottles = 99 To 0 Step -1
If Bottles = 0 Then
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.")
Console.ReadLine()
ElseIf Bottles = 1 Then
Console.WriteLine(Bottles & " bottle of beer on the wall, " & Bottles & " bottle of beer.")
Console.WriteLine("Take one down and pass it around, no more bottles of beer on the wall.")
Console.ReadLine()
Else
Console.WriteLine(Bottles & " bottles of beer on the wall, " & Bottles & " bottles of beer.")
Console.WriteLine("Take one down and pass it around, " & (Bottles - 1) & " bottles of beer on the wall.")
Console.ReadLine()
End If
Next
End Sub
End Module

[edit] Whenever

 
1 defer (4 || N(1)<N(2) && N(2)<N(3)) print(N(1)+" bottles of beer on the wall, "+N(1)+" bottles of beer,");
2 defer (4 || N(1)==N(2)) print("Take one down and pass it around,");
3 defer (4 || N(2)==N(3)) print(N(1)+" bottles of beer on the wall.");
4 1#98,2#98,3#98;

[edit] X86 Assembly

Using Windows/MASM32.

.386
.model flat, stdcall
option casemap :none
 
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
 
.DATA
buffer db 1024 dup(?)
str1 db "%d bottles of beer on the wall.",10,13,0
str2 db "%d bottles of beer",10,13,0
str3 db "Take one down, pass it around",10,13,0
str4 db "No more bottles of beer on the wall!",10,13,0
nline db 13,10,0
 
bottles dd 99
 
.CODE
start:
INVOKE wsprintfA, offset buffer, offset str1, [bottles]
INVOKE StdOut, offset buffer
 
INVOKE wsprintfA, offset buffer, offset str2, [bottles]
INVOKE StdOut, offset buffer
 
INVOKE StdOut, offset str3
 
DEC [bottles]
 
INVOKE wsprintfA, offset buffer, offset str1, [bottles]
INVOKE StdOut, offset buffer
INVOKE StdOut, offset nline
 
CMP [bottles], 1
JNE start
 
INVOKE StdOut, offset str4
INVOKE ExitProcess, 0
end start
Personal tools
Support