99 bottles of beer: Difference between revisions
Added uBasic/4tH version |
|||
Line 6,570: | Line 6,570: | ||
repetitions of the integer sequences 99 98 ... 0. |
repetitions of the integer sequences 99 98 ... 0. |
||
=={{header|uBasic/4tH}}== |
|||
A very vanilla BASIC implementation. |
|||
<lang>0005 LET I=99 |
|||
0006 PRINT "Lyrics of the song 99 Bottles of Beer" |
|||
0010 REM main |
|||
0011 IF I>2 THEN GOTO 20 |
|||
0012 IF I=2 THEN GOTO 30 |
|||
0013 IF I=1 THEN GOTO 40 |
|||
0014 GOTO 50 |
|||
0020 REM if greater than two |
|||
0021 PRINT I;" Bottles of beer on the wall, ";I;" bottles of beer." |
|||
0022 LET I=I-1 |
|||
0023 PRINT "Take one down and pass it around, "; |
|||
0024 PRINT I;" bottles of beer on the wall." |
|||
0025 GOTO 10 |
|||
0030 REM if equals two |
|||
0031 PRINT I;" Bottles of beer on the wall, ";I;" bottles of beer." |
|||
0032 LET I=I-1 |
|||
0033 PRINT "Take one down and pass it around, "; |
|||
0034 PRINT I;" bottle of beer on the wall." |
|||
0035 GOTO 10 |
|||
0040 REM if equals one |
|||
0041 PRINT I;" Bottle of beer on the wall, ";I;" bottle of beer." |
|||
0042 LET I=I-1 |
|||
0043 PRINT "Take one down and pass it around,"; |
|||
0044 PRINT " no more bottles of beer on the wall." |
|||
0045 GOTO 10 |
|||
0050 REM if equals zero then exit |
|||
0051 PRINT "No more bottles of beer on the wall. No more bottles of beer..." |
|||
0052 PRINT "Go to the store and buy some more...99 bottles of beer." |
|||
</lang> |
|||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
See [[99 Bottles of Beer/Shell]] |
See [[99 Bottles of Beer/Shell]] |
Revision as of 08:50, 30 October 2015
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
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
0815
See 99 Bottles of Beer/EsoLang
360 Assembly
See 99 Bottles of Beer/Assembly
6502 Assembly
See 99 Bottles of Beer/Assembly
6800 Assembly
See 99 Bottles of Beer/Assembly
8th
<lang forth> \ 99 bottles of beer on the wall:
- allout "no more bottles" ;
- just-one "1 bottle" ;
- yeah! dup . " bottles" ;
[ ' allout , ' just-one , ' yeah! , ] var, bottles
- .bottles dup 2 n:min bottles @ swap caseof ;
- .beer .bottles . " of beer" . ;
- .wall .beer " on the wall" . ;
- .take " Take one down and pass it around" . ;
- beers .wall ", " . .beer '; putc cr
n:1- 0 max .take ", " . .wall '. putc cr drop ;
' beers 1 99 loop- bye </lang>
ABAP
<lang 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.</lang>
ACL2
ActionScript
<lang 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"); }</lang>
Ada
Simple version
<lang ada>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;</lang>
Concurrent version
with 1 task to print out the information and 99 tasks to specify the number of bottles <lang Ada>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;</lang>
Aime
<lang 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;
}</lang>
ALGOL 68
<lang algol68>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
)</lang>
AmigaE
<lang 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</lang>
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. <lang xml><?xml version="1.0"?> <project name="n bottles" default="99_bottles">
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<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"/>
<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></lang>
APL
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
App Inventor
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>
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>
AppleScript
<lang 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!"</lang>
Arbre
<lang 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
</lang>
Argile
<lang 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") }</lang>
ARM Assembly
See 99 Bottles of Beer/Assembly
ATS
<lang 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)</lang>
AutoHotkey
AutoIt
AWK
Regular version
If you don't want so many beers, here you can specify the starting amount.
For example, just a sixpack:
<lang awk># 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!" }</lang>
- 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!
Bottled version
Axe
Pauses are added to accommodate the small calculator screen so all of the text can be read.
<lang axe>99→B While B
Disp B▶Dec," BOTTLES OF","BEER ON THE WALL" Disp B▶Dec," BOTTLES OF","BEER",i,i getKeyʳ Disp "TAKE ONE DOWN",i,"PASS IT AROUND",i B-- Disp B▶Dec," BOTTLES OF","BEER ON THE WALL",i getKeyʳ
End</lang>
Babel
<lang 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]</lang>
BASIC
FBSL
Integer BASIC
Liberty BASIC
OxygenBasic
PureBasic
REALbasic
Run BASIC
TI-83 BASIC
TI-89 BASIC
Visual Basic
Batch File
Battlestar
<lang c> 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: </lang>
Befunge
See 99 Bottles of Beer/EsoLang
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: <lang bracmat>{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; </lang>
Brainf***
See 99 Bottles of Beer/EsoLang
Brat
<lang 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."</lang>
C
The simple solution
<lang c>#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;
}</lang>
A recursive solution
<lang c>#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;
}</lang>
Code golf
<lang c>#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");}</lang>
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:
<lang c>#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;
}</lang>
An inspection of the generated executable proves that it indeed contains the complete text of the song in one block.
The bottled version
WYSIWYG (with correct plurals and can buy some more):<lang c> 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);}</lang>
C++
The simple solution
<lang cpp>#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"; }
}</lang>
An object-oriented solution
See: 99 Bottles of Beer/C++/Object Oriented
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:
<lang cpp>#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;
}</lang>
A Recursive solution
<lang cpp>#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; } </lang>
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:
<lang cpp>#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;
}</lang>
Bottled Version
<lang cpp> //>,_
//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!!!</lang>
C#
<lang csharp>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(); } } }
}</lang>
Another Implementation using Linq
<lang csharp>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); } }
}</lang>
Flexible Version
<lang csharp>
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); } } }
</lang>
Using Formatting
<lang csharp> 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...."); } }
}</lang>
- 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....
Using iterator blocks
<lang csharp>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)); }
}</lang>
A Fun One
<lang csharp> 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(); } </lang>
Using recursion
<lang csharp>
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); } }
</lang>
Clay
<lang 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)))));
} </lang>
Chapel
copied from http://99-bottles-of-beer.net/language-chapel-1215.html, with minor modifications for chapel 1.7
<lang Chapel> /***********************************************************************
* 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: chapel_info@cray.com * * * 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, ";
} </lang>
Chef
See 99 Bottles of Beer/EsoLang
CLIPS
<lang 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)))))</lang>
Clojure
<lang 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)</lang>
Or, using cl-format:
<lang Clojure>(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))</lang>
COBOL
Free form version. <lang cobol>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.</lang>
Another free-form version, without using DISPLAY NO ADVANCING
.
<lang cobol>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.</lang>
A more concise version that adheres to the minimum guidelines. Leading zeros are not suppressed. (OpenCOBOL - 1.1.0) <lang cobol>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.</lang>
CoffeeScript
<lang 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]
</lang>
With completely different approach...
<lang coffeescript>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'
</lang>
or as a one liner...
<lang coffeescript>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]</lang>
or another completely different one liner
<lang coffeescript>((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]</lang>
ColdFusion
Classic tag based CFML
<lang cfm><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
#x# bottle#plur# of beer
Take one down, pass it around
#iif(x is 1,DE("No more"),"x-1")# bottle#iif(x is 2,"",DE("s"))# of beer on the wall
</cfloop>
</cfoutput></lang> or if you prefer: (identical output, grammatically correct to the last stanza)
CFScript
<lang cfm><cfscript>
for (x=99; x gte 1; x--) { plur = iif(x==1,,DE('s')); WriteOutput("#x# bottle#plur# of beer on the wall
#x# bottle#plur# of beer
Take one down, pass it around
#iif(x is 1,DE('No more'),'x-1')# bottle#iif(x is 2,,DE('s'))# of beer on the wall
"); }
</cfscript></lang>
Common Lisp
Component Pascal
D
Simple Solution
Based on Steward Gordon's code at: 99-bottles-of-beer.net. <lang d>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.");
}</lang>
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.
<lang d>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() {}</lang>
Template Meta-Programming Solution
Uses D template meta-programming and recursion to pre-generate the song lyrics and prints it at compile via pragma(msg,...)
<lang d> module bottles;
template BeerSong(int Bottles) { static if (Bottles == 1) { enum BeerSong = "1 bottle of beer on the wall\n" ~ "1 bottle of beer\ntake it down, pass it around\n" ~ " no more bottles of beer on the wall\n"; } else { enum BeerSong = Bottles.stringof ~ " bottles of beer on the wall\n" ~ Bottles.stringof ~ " bottles of beer\ntake it down, pass it around\n" ~ BeerSong!(Bottles-1); } }
pragma(msg,BeerSong!99);
void main(){} </lang>
Dart
<lang 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(""); }
}</lang>
Delphi
Déjà Vu
<lang dejavu>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</lang>
Dylan
<lang 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</lang>
E
<lang 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. `) }</lang>
ECL
<lang 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); </lang>
EGL
<lang 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</lang>
Eiffel
<lang 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 </lang>
An alternative version written using the across-loop construct. <lang eiffel> output_lyrics -- Output the lyrics to 99-bottles-of-beer. local l_bottles: LINKED_LIST [INTEGER] do create l_bottles.make across (1 |..| 99) as ic loop l_bottles.force (ic.item) end across l_bottles.new_cursor.reversed as ic_bottles loop print (ic_bottles.item) print (" bottles of beer on the wall, ") print (ic_bottles.item) print (" bottles of beer.%N") print ("Take one down, pass it around, ") if ic_bottles.item > 1 then print (ic_bottles.item) print (" bottles of beer on the wall.%N%N") end end print ("1 bottle of beer on the wall.%N") print ("No more bottles of beer on the wall, no more bottles of beer.%N") print ("Go to the store and buy some more, 99 bottles of beer on the wall.%N") end
</lang>
Ela
<lang 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]</lang>
Elixir
<lang 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</lang>
Erlang
<lang 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.</lang>
Euphoria
This is based on the Batch File example. <lang Euphoria> 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</lang>
Extended BrainF***
See 99 Bottles of Beer/EsoLang
F#
<lang fsharp>#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)</lang>
Factor
<lang 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</lang>
Falcon
<lang 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</lang>
A more robust version to handle plural/not plural conditions <lang falcon>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</lang>
FALSE
See 99 Bottles of Beer/EsoLang
ferite
copied from 99-bottles-of-beer.net.
<lang ferite>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.");</lang>
Fexl
<lang fexl> \suffix=(\n eq n 1 "" "s") \sing_count=(\n put [n " bottle" (suffix n) " of beer"]) \sing_line1=(\n sing_count n say " on the wall") \sing_line2=(\n sing_count n nl) \sing== (\n le n 0 (); sing_line1 n sing_line2 n say "Take one down, pass it around" \n=(- n 1) sing_line1 n nl sing n ) sing 3 </lang>
- 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
Forth
<lang 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</lang>
Version 2: create a beer language and write the program <lang forth>: bottles ( n -- ) \ select the right grammar based on 'n'
dup case 1 of ." One more bottle " drop endof 0 of ." No more bottles " drop endof . ." bottles " \ default case endcase ;
\ create punctuation with delay for artistic effect
- , [char] , emit 100 ms ;
- . [char] . emit 300 ms ;
\ create the words to write the program
- of ." of " ;
- beer ." beer " ;
- on ." on " ;
- the ." the " ;
- wall ." wall" ;
- take ." take " ;
- one ." one " ;
- down ." down" ;
- pass ." pass " ;
- it ." it " ;
- around ." around" ;
\ who said Forth is write only?
- beers ( n -- ) \ USAGE: 99 beers
1 swap cr do I bottles of beer on the wall , cr I bottles of beer , cr take one down , pass it around , cr I 1- bottles of beer on the wall . cr cr -1 +loop ;</lang>
Forth Console Output <lang Forth>2 beers 2 bottles of beer on the wall, 2 bottles of beer , take one down, pass it around, One more bottle 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.
ok</lang>
Fortran
F90 version
<lang 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</lang>
MPI version
<lang fortran>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</lang>
Usage:
mpif90 filename.f90 mpiexec -np 99 a.out
Fortran 2003/2008 OOP version
Works with GNU gfortran 5.0.0 and Intel ifort 15.0.2 <lang fortran> module song_typedefs
implicit none
private ! all public :: TBottles
type, abstract :: TContainer integer :: quantity contains ! deferred method i.e. abstract method = must be overridden in extended type procedure(take_one), deferred, pass :: take_one procedure(show_quantity), deferred, pass :: show_quantity end type TContainer
abstract interface subroutine take_one(this) import TContainer implicit none class(TContainer) :: this end subroutine take_one subroutine show_quantity(this) import TContainer implicit none class(TContainer) :: this end subroutine show_quantity end interface
! extended derived type type, extends(TContainer) :: TBottles contains procedure, pass :: take_one => take_one_bottle procedure, pass :: show_quantity => show_bottles final :: finalize_bottles end type TBottles
contains
subroutine show_bottles(this) implicit none class(TBottles) :: this ! integer :: show_bottles character(len=*), parameter :: bw0 = "No more bottles of beer on the wall," character(len=*), parameter :: bwx = "bottles of beer on the wall," character(len=*), parameter :: bw1 = "bottle of beer on the wall," character(len=*), parameter :: bb0 = "no more bottles of beer." character(len=*), parameter :: bbx = "bottles of beer." character(len=*), parameter :: bb1 = "bottle of beer." character(len=*), parameter :: fmtxdd = "(I2,1X,A28,1X,I2,1X,A16)" character(len=*), parameter :: fmtxd = "(I1,1X,A28,1X,I1,1X,A16)" character(len=*), parameter :: fmt1 = "(I1,1X,A27,1X,I1,1X,A15)" character(len=*), parameter :: fmt0 = "(A36,1X,A24)"
select case (this % quantity) case (10:) write(*,fmtxdd) this % quantity, bwx, this % quantity, bbx case (2:9) write(*,fmtxd) this % quantity, bwx, this % quantity, bbx case (1) write(*,fmt1) this % quantity, bw1, this % quantity, bb1 case (0) write(*,*) write(*,fmt0) bw0, bb0 case default write(*,*)"Warning! Number of bottles exception, error 42. STOP" stop end select ! show_bottles = this % quantity end subroutine show_bottles
subroutine take_one_bottle(this) ! bind(c, name='take_one_bottle') implicit none class(TBottles) :: this ! integer :: take_one_bottle character(len=*), parameter :: t1 = "Take one down and pass it around," character(len=*), parameter :: remx = "bottles of beer on the wall." character(len=*), parameter :: rem1 = "bottle of beer on the wall." character(len=*), parameter :: rem0 = "no more bottles of beer on the wall." character(len=*), parameter :: fmtx = "(A33,1X,I2,1X,A28)" character(len=*), parameter :: fmt1 = "(A33,1X,I2,1X,A27)" character(len=*), parameter :: fmt0 = "(A33,1X,A36)"
this % quantity = this % quantity -1
select case (this%quantity) case (2:) write(*,fmtx) t1, this%quantity, remx case (1) write(*,fmt1) t1, this%quantity, rem1 case (0) write(*,fmt0) t1, rem0 case (-1) write(*,'(A66)') "Go to the store and buy some more, 99 bottles of beer on the wall." case default write(*,*)"Warning! Number of bottles exception, error 42. STOP" stop end select
end subroutine take_one_bottle
subroutine finalize_bottles(bottles) implicit none type(TBottles) :: bottles ! here can be more code end subroutine finalize_bottles
end module song_typedefs
!----------------------------------------------------------------------- !Main program !----------------------------------------------------------------------- program bottles_song
use song_typedefs implicit none integer, parameter :: MAGIC_NUMBER = 99 type(TBottles), target :: BTLS
BTLS = TBottles(MAGIC_NUMBER)
call make_song(BTLS)
contains
subroutine make_song(bottles) type(TBottles) :: bottles do while(bottles%quantity >= 0) call bottles%show_quantity() call bottles%take_one() enddo end subroutine make_song
end program bottles_song </lang>
Frege
(identical to the Haskell, apart from adding the module declaration)
<lang frege>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"</lang>
friendly interactive shell
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. <lang frink> 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" </lang>
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.
FunL
<lang 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) )</lang>
GAP
<lang 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;</lang>
gnuplot
<lang 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</lang>
Go
No sense of humor
<lang go>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)) } }</lang>
Typoglycemic
With code from RC tasks Number names, Knuth shuffle. <lang go>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, " ")
}</lang>
- 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
Go!
Copied from The 99 Bottles of Beer web site with a minor bug fix. <lang go!>-- -- 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".
}</lang>
Gosu
<lang 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("");
} </lang>
Golfscript
<lang 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</lang>
Groovy
Basic Solution
With a closure to handle special cardinalities of bottles. <lang groovy>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 """ }</lang>
Single Print Version
Uses a single print algorithm for all four lines. Handles cardinality on bottles, uses 'No more' instead of 0. <lang groovy>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"
}</lang>
Bottomless Beer Solution
Using more closures to create a richer lyrical experience. <lang groovy>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) // }</lang>
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:
<lang guiss>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] </lang> We haven't drank all of the bottles at this point, but we can keep going, if we want.
GW-BASIC
Just a basic loop counting down to one. No big deal. Note that at BOTTLES=1, it is not grammatically correct.
<lang qbasic>10 FOR BOTTLES = 99 TO 1 STEP -1 20 PRINT BOTTLES " bottles of beer on the wall" 30 PRINT BOTTLES " bottles of beer" 40 PRINT "Take one down, pass it around" 50 PRINT BOTTLES-1 " bottles of beer on the wall" 60 NEXT BOTTLES </lang>
Haskell
A relatively concise solution:
<lang haskell>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"</lang>
As a list comprehension:
<lang haskell>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"</lang>
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.
<lang haskell>{-# 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</lang>
Haxe
Simple solution
<lang haxe>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--; } }
}</lang>
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.
<lang haxe>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}); }
}</lang>
HicEst
<lang 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</lang>
HQ9+
See 99 Bottles of Beer/EsoLang
Icon and Unicon
The default is 99 bottles, but you can change this on the command line for really long trips... <lang icon>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</lang>
IDL
<lang 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
</lang>
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:
<lang IDL>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</lang>
Idris
<lang Idris> beerSong : Fin 100 -> String beerSong x = verses x where
bottlesOfBeer : Fin n -> String bottlesOfBeer fZ = "No more bottles of beer" bottlesOfBeer (fS fZ) = "1 bottle of beer" bottlesOfBeer k = (show (finToInteger k)) ++ " bottles of beer"
verse : Fin n -> String verse fZ = "" verse (fS n) = (bottlesOfBeer (fS n)) ++ " on the wall,\n" ++ (bottlesOfBeer (fS n)) ++ "\n" ++ "Take one down, pass it around\n" ++ (bottlesOfBeer n) ++ " on the wall\n"
verses : Fin n -> String verses fZ = "" verses (fS n) = (verse (fS n)) ++ (verses n)
</lang>
Inform 6
<lang inform6>[ 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);
]; </lang>
Inform 7
Programmatic solution
<lang inform7>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.</lang>
World model solution
This solution uses in-game objects to represent the wall and the bottles.
<lang inform7>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".</lang>
Intercal
See 99 Bottles of Beer/EsoLang
Io
<lang 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" )
)</lang>
Ioke
<lang 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
)</lang>
J
As posted at the J wiki <lang j>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</lang>
- 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
Java
Console
MessageFormat's choice operator is used to properly format plurals. <lang java>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"); } }
}</lang>
Optimized <lang java>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()); }
}</lang>
Recursive <lang java>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); } } }</lang>
An object-oriented solution
See: 99 Bottles of Beer/Java/Object Oriented
GUI
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. <lang java>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 } }
}</lang>
JavaScript
ES3-5
<lang javascript>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--;
} </lang>
ES6
<lang javascript>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--;
}</lang>
Other Examples
More skilled solution "one-liner" with grammar check
<lang javascript>// 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
" + beer + " bottle" + (beer != 1 ? "s" : "") + " of beer
Take one down, pass it around
" + (--beer) + " bottle" + (beer != 1 ? "s" : "") + " of beer on the wall
" );</lang>
Object Oriented <lang javascript>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();</lang>
An alternative version:
<lang javascript>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 = '
' 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;</lang>
Joy
<lang 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 .</lang>
jq
Minimalist: <lang jq>99 | (. - range(0;.+1) ) | " \(.) bottles of beer on the wall \(.) bottles of beer Take one down, pass it around \(.) bottles of beer on the wall"</lang>
- Output:
<lang sh>$ jq -n -r -f 99_bottles.jq ...
2 bottles of beer on the wall 2 bottles of beer Take one down, pass it around 2 bottles of beer on the wall
1 bottles of beer on the wall 1 bottles of beer Take one down, pass it around 1 bottles of beer on the wall
0 bottles of beer on the wall 0 bottles of beer Take one down, pass it around 0 bottles of beer on the wall</lang> Variant: <lang jq>def sing:
def s: if . == 1 then "" else "s" end; def bottles: if . == 0 then "No more" else "\(.)" end + " bottle\(s)"; (. - range(0;.+1) ) | "
\(bottles) of beer on the wall \(bottles) of beer Take one down, pass it around \(bottles) of beer on the wall."
$bottles | tonumber | sing</lang>
- Output:
<lang sh>$ jq -r --arg bottles 99 -f 99_bottles_variant.jq ... 2 bottles of beer on the wall 2 bottles of beer Take one down, pass it around 2 bottles of beer on the wall.
1 bottle of beer on the wall 1 bottle of beer Take one down, pass it around 1 bottle of beer on the wall.
No more bottles of beer on the wall No more bottles of beer Take one down, pass it around No more bottles of beer on the wall.</lang>
Julia
one-liner <lang julia>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</lang> another solution, handling grammar cases "No more bottles", "1 bottle", "<n> bottles" <lang julia>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</lang> shorter, but more cryptic, version of the previous `bottles` function <lang julia>bottles(n) = "$(n==0 ? "No more" : n) bottle$(n==1 ? "" : "s")"</lang>
K
<lang 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</lang>
Kotlin
<lang kotlin>fun main(args: Array<String>) {
for (i in 99.downTo(1)) { println("${i} bottles of beer on the wall") println("${i} bottles of beer") println("Take one down, pass it around") } println("No more bottles of beer on the wall!")
} </lang>
LabVIEW
Lasso
Simple loop
<lang Lasso>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</lang>
Query Expression
<lang Lasso>(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')</lang>
Query Expression with Autocollect
<lang Lasso>// 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,
' #n + ' bottle' + #s + ' of beer,
' #n = #n - 1 #s = (#n != 1 ? 's' | ) 'Take one down, pass it around,
' #n + ' bottle' + #s + ' of beer on the wall.
'
^}</lang>
LaTeX
Recursive
<lang LaTeX>\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}</lang>
Iterative
The \loop macro is tail-recursive (Knuth 1984, page 219). Just for fun, this version uses Roman numerals.
<lang LaTeX>\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}</lang>
References
- Knuth, Donald E. (1984). The TeXbook, Addison Wesley.
lang5
<lang 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</lang>
Lhogho
<lang logo>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</lang>
LiveCode
<lang 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</lang>
Lisp
LLVM
See 99 Bottles of Beer/Assembly
Logo
<lang 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)]</lang>
Logtalk
<lang 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.</lang>
LOLCODE
See 99 Bottles of Beer/EsoLang
Lua
<lang 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</lang>
With a numeric for-loop and string formatting:
<lang lua>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</lang>
Lucid
<lang 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</lang>
M4
<lang 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)</lang>
make
BSD make
<lang 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.</lang>
Usage: make or make START=99
GNU make
<lang 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,"</lang>
Usage: make 99-bottles
This will fork 99 make processes. You might need to raise your process limit (ulimit -p).
GNU make
Without using a shell command to decrement the counter
<lang make>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 "" </lang>
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.
Maple
<lang Maple>seq( printf( "%d %s of beer on the wall,\n%d %s of beer.\nTake one down, pass it around,\n%d %s of beer on the wall.\n\n",
i, `if`( i<>1, "bottles", "bottle" ), i, `if`( i<>1, "bottles", "bottle" ), i-1, `if`( i-1<>1, "bottles", "bottle") ),
i = 99..1, -1 );</lang>
Mathematica / Wolfram Language
<lang 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]</lang>
MATLAB
<lang 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</lang>
Maxima
<lang 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
- /</lang>
MAXScript
<lang 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
)</lang>
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.
<lang maxscript>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 "")))</lang>
Mirah
<lang 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 </lang>
mIRC Scripting Language
<lang mirc>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
}</lang>
mLite
<lang sml>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")</lang> 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
ML/I
Simple iterative version
<lang ML/I>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</lang>
Recursive version
<lang ML/I>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</lang>
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.
<lang ML/I> 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. </lang>
Usage:
ml1 "Bottles of Beer.ml1"
Output:
<lang ML/I> 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!
</lang>
Modula-2
<lang modula2>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.</lang>
Modula-3
<lang modula3>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.</lang>
Monkey
Tic's every one and a half seconds and sings(text's) the song out. <Lang monkey>
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
</lang>
MOO
<lang 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.");</lang>
MoonScript
<lang 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'</lang>
MUMPS
Recursive
<lang MUMPS>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)</lang>
Iterative
<lang MUMPS>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)</lang>
NASL
<lang 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;</lang>
Nemerle
<lang 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) }
}</lang>
NetRexx
<lang 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 </lang>
NewLISP
Nial
<lang 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</lang>
Nim
<lang nim>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."</lang>
other:
<lang nim>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</lang>
compact:
<lang nim>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))</lang>
organized:
<lang nim>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))</lang>
OASYS
<lang oasys_oac> class player {}
int count
property int dummy
method quit verbs Template:Quit {
quit
}
method beer verbs Template:Beer {
count = 99 while count { print count print " bottles of beer on the wall.\n" print count print " bottles of beer.\nTake one down and pass it around,\n" count = count - 1 if count { print count print " bottles of beer on the wall.\n\n" } } print "No more bottles of beer on the wall.\n"
}
method init {
player = create player print "Type 'beer' for beer.\nType 'quit' to quit.\n"
} </lang>
OASYS Assembler
See 99 Bottles of Beer/Assembly
Objective-C
<lang objc>#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;
}</lang>
Oberon-2
<lang oberon2>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.</lang>
OCaml
For-loop
<lang 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</lang>
Recursive
Recursive version that handles plurals.
<lang ocaml>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;;</lang>
Monadic
Monadic version, expressing actions which evolve the program state and log output. Special cases and grammar rules are handled.
<lang ocaml>(* A basic "Writer" monoid with emit *) module Writer = struct
type 'a t = 'a * string let ( >>= ) (x,s) f = let (y,s') = f x in (y, s ^ s') let return x = (x,"") let emit (x,s) = print_string s; x
end
(* Utility functions for handling strings and grammar *) let line s = (String.capitalize s) ^ ".\n" let count = function 0 -> "no more" | n -> string_of_int n let plural = function 1 -> "" | _ -> "s" let specify = function 1 -> "it" | _ -> "one" let bottles n = count n ^ " bottle" ^ plural n ^ " of beer"
(* Actions, expressed as an int * string, for Writer *) let report n = (n, line (bottles n ^ " on the wall, " ^ bottles n)) let take n = (n-1, "Take " ^ specify n ^ " down and pass it around") let summary n = (n, ", " ^ bottles n ^ " on the wall.\n\n") let shop = (99, "Go to the store and buy some more")
let rec verse state =
Writer.(state >>= report >>= function 0 -> shop >>= summary (* ends here *) | n -> take n >>= summary |> verse)
let sing start =
Writer.(emit (verse (return start)))</lang>
Output for initial beer-count of two:
<lang># sing 2;; 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 it 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.
- : int = 99</lang>
Note the output value is 99... reflecting the state at termination.
Octave
<lang 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);</lang>
Oforth
<lang Oforth>"bottles of beer on the wall\n" Constant new: B "bottles of beer\nTake one down, pass it around\n" Constant new: T
- beer { 100 seq reverse apply(#[ dup . B print dup . T print 1 - . B print printcr ]) }</lang>
OOC
<lang 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) }
} </lang>
ooRexx
The rexx example below runs unchanged on ooRexx
OpenEdge/Progress
<lang Progress (Openedge ABL)>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 "{>s} " 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.</lang>
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.
"Pure" Order
This solution uses only Order language constructs to generate and manipulate tokens: <lang c>#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)))</lang>
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: <lang c>#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</lang>
Either example could obviously also form the core of a C solution (demonstrating the intended use of Order).
Oxygene
<lang 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. </lang>
Oz
Constraint Programming
Note: In real life, you would never solve a simple iterative task like this with constraint programming. This is just for fun. <lang oz>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}</lang>
Iterative
<lang oz>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</lang>
PARI/GP
<lang parigp>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")</lang>
Pascal
Perl
<lang 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;
}</lang>
Alternatively: <lang perl>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")) ); }</lang>
Correct grammar and nice spacing in modern perl: <lang 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.";</lang>
Using perl5 as a DSL factory leveraging $_'s global nature: <lang perl>
- !/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;</lang>
Perl 6
A Simple Way
<lang perl6>my $b = 99;
repeat while --$b {
say "{b $b} on the wall"; say "{b $b}"; say "Take one down, pass it around"; say "{b $b-1} on the wall"; say "";
}
sub b($b) {
"$b bottle{'s' if $b != 1} of beer";
}</lang>
A Clearer Way
Similar to "A Simple Way", but with proper variable and subroutine naming, declarator documentation, strongly-typed function definition, better code reuse, and external ternary logic.
<lang perl6>for 99...1 -> $bottles {
sing $bottles, :wall; sing $bottles; say "Take one down, pass it around"; sing $bottles - 1, :wall; say "";
}
- | Prints a verse about a certain number of beers, possibly on a wall.
sub sing(
Int $number, #= Number of bottles of beer. Bool :$wall, #= Mention that the beers are on a wall?
) {
my $quantity = $number == 0 ?? "No more" !! $number; my $plural = $number == 1 ?? "" !! "s"; my $location = $wall ?? " on the wall" !! ""; say "$quantity bottle$plural of beer$location"
}</lang>
A More Extravagant Way
<lang perl6>my @quantities = flat (99 ... 1), 'No more', 99; my @bottles = flat 'bottles' xx 98, 'bottle', 'bottles' xx 2; my @actions = flat '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";
}</lang>
Phix
<lang phix>constant ninetynine = 99 -- (set this to 9 for testing)
function bottles(integer count)
if count=0 then return "no more bottles " elsif count=1 then return "1 bottle " end if if count=-1 then count = ninetynine end if return sprintf("%d bottles ",count)
end function
function bob(integer count)
return bottles(count)&"of beer"
end function
function up1(string bob) -- Capitalise sentence start (needed just the once, "no more"=>"No more")
bob[1] = upper(bob[1]) return bob
end function
string this = bob(ninetynine) string that = "Take one down, pass it around,\n"
for i=ninetynine to 0 by -1 do puts(1,up1(this)&" on the wall,\n") puts(1,this&".\n") if i=0 then that = "Go to the store, buy some more,\n" elsif i=1 then that[6..8] = "it" end if this = bob(i-1) puts(1,that&this&" on the wall.\n\n") end for if getc(0) then end if
</lang>
PHL
<lang phl>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;
]</lang>
PHP
<lang 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";
} ?></lang>
shorter way
<lang php><?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";
?></lang>
modifing way:
<lang php><?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;
} ?></lang>
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 <lang php><?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):""); }</lang>
gettext alternative
supports grammar and translations.
<lang php><?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</lang>
PicoLisp
Piet
See 99 Bottles of Beer/EsoLang
Pike
<lang 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");
}</lang>
alternate version: <lang Pike>// 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);
}</lang>
PIR
<lang pir>.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</lang>
Plain TeX
<lang tex>\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</lang>
Pop11
<lang 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);</lang>
PostScript
<lang 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</lang>
PowerShell
ProDOS
Prolog
Python
Qore
Simple Solution
<lang qore>#!/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);
}</lang>
Concurrent (Unordered) Solution
<lang qore>#!/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();</lang>
Quill
<lang 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</lang>
R
Simple looping solution
<lang rsplus>#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</lang>
Vector solutions
<lang rsplus>#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'))</lang>
Ra
<lang Ra> class BottlesOfBeer **Prints the "99 Bottles of Beer" song"**
on start
args := program arguments
# If no arguments given, print the song once if args empty .printSong
# Otherwise, print the song the given number of times else .printSong(integer.parse(args[0]))
shared
define printSong(times := 1) **Print the song the given number of times**
for times, _printSong
define _printSong **Print the song**
# Print for bottles 99 to 1 for bottle in 99 to 0 by -1
print "[_bottles(bottle)] of beer on the wall [_bottles(bottle)] of beer Take one down, pass it around [_bottles(bottle - 1)] of beer on the wall "
print "No more bottles of beer on the wall No more bottles of beer Go to the store, buy some more 99 bottles of beer on the wall"
define _bottles(bottle as integer) as String ** If bottle is 0, returns "No more bottles" If bottle is 1, returns "1 bottle" Otherwise, returns "[bottle] bottles" **
if bottle = 0, return "No more bottles" if bottle = 1, return "1 bottle" return "[bottle] bottles" </lang>
Racket
<lang 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) </lang>
RapidQ
<lang 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 </lang>
Rascal
<lang 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.");
} </lang>
Raven
<lang 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</lang>
- 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.
REBOL
<lang 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 ]]</lang>
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:
<lang REBOL>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</lang>
Here's a simple 1 line console version:
<lang REBOL>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"^/"]]</lang>
Retro
This is based on the Forth example.
<lang Retro>[ 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</lang>
REXX
<lang 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*/</lang> 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.
RPL/2
Simple solution
<lang rpl/2>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" +
>></lang>
Recursive and multithreaded solution
<lang rpl/2>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
>></lang>
Ruby
<lang 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</lang>
Ruby has variable traces, so we can do <lang ruby>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</lang> or... <lang ruby>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</lang> or... <lang ruby>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</lang>
Simple solution
<lang ruby> 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 </lang>
Rust
<lang rust>trait Bottles { fn bottles_of_beer(&self) -> Self; fn on_the_wall(&self); }
impl Bottles for u32 { fn bottles_of_beer(&self) -> u32 { match *self { 0 => print!("No bottles of beer"), 1 => print!("{} bottle of beer", self), _ => print!("{} bottles of beer", self) } *self // return a number for chaining }
fn on_the_wall(&self) { println!(" on the wall!"); } }
fn main() { for i in (1..100).rev() { 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!("-----------------------------------"); } }</lang>
Sather
<lang 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;</lang>
Scala
Scheme
<lang 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))))</lang>
Scratch
Scheme
<lang scheme> (define (sing)
(define (sing-to-x n) (if (> n -1) (begin (display n) (display "bottles of beer on the wall") (newline) (display "Take one down, pass it around") (newline) (sing-to-x (- n 1))) (display "would you wanna me to sing it again?"))) (sing-to-x 99))
</lang>
sed
<lang 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</lang>
Seed7
<lang 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;</lang>
Shiny
<lang 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 :)"</lang>
Sidef
<lang ruby>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; );
};</lang>
Simpler: <lang ruby>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.";</lang>
Slate
<lang 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.</lang>
Smalltalk
A straightforward approach: <lang smalltalk>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. ].
].</lang>
SNOBOL4
<lang snobol> 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</lang>
Function
Function version with string composition. Function returns one verse for x bottles. Correctly handles bottle/bottles. <lang SNOBOL4> 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</lang>
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
SNUSP
See 99 Bottles of Beer/EsoLang
Sparkling
<lang 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");</lang>
SQL
<lang SQL> select
( 100 - level ) || ' bottle' || case when level != 99 then 's' end || ' of beer on the wall' || chr(10) || ( 100 - level ) || ' bottle' || case when level != 99 then 's' end || ' of beer' || chr(10) || 'Take one down, pass it around' || chr(10) || ( 99 - level ) || ' bottle' || case when level != 98 then 's' end || ' of beer on the wall' from dual connect by level <= 99;
</lang>
<lang SQL>
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; </lang>
This Statement does also work with T-SQL, but only up to 32 beers
<lang SQL> 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, ;
</lang>
<lang SQL>
/*These statements work in PostgreSQL (tested in 9.3)*/
SELECT generate_series || ' bottles of beer on the wall' || chr(10) || generate_series || ' bottles of beer' || chr(10) || 'Take one down, pass it around' || chr(10) || coalesce(lead(generate_series) OVER (ORDER BY generate_series DESC),0) || ' bottles of beer on the wall' FROM generate_series(1,100) ORDER BY generate_series DESC;
/*The next statement takes also into account the grammaticalt support for "1 bottle of beer".*/
SELECT generate_series || ' bottle' || CASE WHEN generate_series>1 THEN 's' ELSE END || ' of beer on the wall' || chr(10) || generate_series || ' bottle' || CASE WHEN generate_series>1 THEN 's' ELSE END || ' of beer' || chr(10) || 'Take one down, pass it around' || chr(10) || coalesce(lead(generate_series) OVER (ORDER BY generate_series DESC),0) || ' bottle' || CASE WHEN coalesce(lead(generate_series) OVER (ORDER BY generate_series DESC),0) <>1 THEN 's' ELSE END || ' of beer on the wall' FROM generate_series(1,100) ORDER BY generate_series DESC;
/*The next statement uses recursive query.*/
WITH RECURSIVE t(n) AS (
VALUES (1) UNION ALL SELECT n+1 FROM t WHERE n < 100
) SELECT n || ' bottle' || CASE WHEN n>1 THEN 's' ELSE END || ' of beer on the wall' || chr(10) || n || ' bottle' || CASE WHEN n>1 THEN 's' ELSE END || ' of beer' || chr(10) || 'Take one down, pass it around' || chr(10) || coalesce(lead(n) OVER (ORDER BY n DESC),0) || ' bottle' || CASE WHEN coalesce(lead(n) OVER (ORDER BY n DESC),0) <>1 THEN 's' ELSE END || ' of beer on the wall' FROM t ORDER BY n DESC;
</lang>
Squirrel
<lang 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); </lang>
Standard ML
<lang sml>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) )</lang>
Suneido
<lang 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') }</lang>
Swift
<lang swift>for i in reverse(1...99) {
println("\(i) bottles of beer on the wall, \(i) bottles of beer.") let next = i == 1 ? "no" : i.description println("Take one down and pass it around, \(next) bottles of beer on the wall.")
}</lang>
Tcl
Thyrd
TIScript
<lang javascript> 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 );
} </lang>
TorqueScript
<lang 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."); } </lang>
TUSCRIPT
<lang 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 </lang>
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.
<lang txr>@(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)</lang>
To make the song repeat indefinitely, change the first line to:
<lang txr>@(next :list @(mapcar* (fun tostring) (repeat (range 99 0 -1))))</lang>
Now it's processing an infinite lazy lists consisting of repetitions of the integer sequences 99 98 ... 0.
uBasic/4tH
A very vanilla BASIC implementation. <lang>0005 LET I=99 0006 PRINT "Lyrics of the song 99 Bottles of Beer"
0010 REM main 0011 IF I>2 THEN GOTO 20 0012 IF I=2 THEN GOTO 30 0013 IF I=1 THEN GOTO 40 0014 GOTO 50
0020 REM if greater than two 0021 PRINT I;" Bottles of beer on the wall, ";I;" bottles of beer." 0022 LET I=I-1 0023 PRINT "Take one down and pass it around, "; 0024 PRINT I;" bottles of beer on the wall." 0025 GOTO 10
0030 REM if equals two 0031 PRINT I;" Bottles of beer on the wall, ";I;" bottles of beer." 0032 LET I=I-1 0033 PRINT "Take one down and pass it around, "; 0034 PRINT I;" bottle of beer on the wall." 0035 GOTO 10
0040 REM if equals one 0041 PRINT I;" Bottle of beer on the wall, ";I;" bottle of beer." 0042 LET I=I-1 0043 PRINT "Take one down and pass it around,"; 0044 PRINT " no more bottles of beer on the wall." 0045 GOTO 10
0050 REM if equals zero then exit 0051 PRINT "No more bottles of beer on the wall. No more bottles of beer..." 0052 PRINT "Go to the store and buy some more...99 bottles of beer." </lang>
UNIX Shell
UnixPipes
Ursala
<lang 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</lang>
V
<lang v>[bottles
[newline '' 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</lang>
Vala
<lang 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);
}</lang>
VBA
VBScript
Visual Prolog
Vox
<lang 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" );
</lang>
Wart
Whenever
See 99 Bottles of Beer/EsoLang
Wortel
<lang 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"
}</lang>
Wrapl
<lang 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}, {(i@String.T):lower} bottle{s} {ob}.\n{more}');
);
Out:write(verse[2,0]@(String.T, "") + verse[1]);
END Bottles.</lang>
Wren
<lang wren>for (i in 99...0) {
IO.print(i, " bottles of beer on the wall,") IO.print(i, " bottles of beer,") IO.print("Take one down, pass it around,") IO.print(i - 1, " bottles of beer on the wall.\n")
}</lang>
X86 Assembly
See 99 Bottles of Beer/Assembly
xEec
Xojo
Place the following in the Open event handler of a Console application: <lang vb>Dim bottles As Integer = 99 While bottles > 0
Print(bottles.ToText) + " bottles of beer on the wall,") Print(bottles.ToText + " bottles of beer.") Print("Take one down, pass it around.") bottles = bottles - 1 Print(bottles.ToText + " bottles of beer on the wall.") Print ""
Wend</lang>
XPL0
<lang 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; ]</lang>
XSLT
XSLT 1.0
To run, transform any document with this stylesheet (the input document is ignored).
<lang xml><?xml version="1.0" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="/"> <xsl:call-template name="sing-all-verses-in-range"/> </xsl:template>
<xsl:template name="sing-all-verses-in-range"> <xsl:param name="first" select="99"/> <xsl:param name="final" select="1"/> <xsl:if test="$first >= $final"> <xsl:call-template name="sing-verse-starting-with-number"> <xsl:with-param name="n" select="$first"/> </xsl:call-template> <xsl:call-template name="sing-all-verses-in-range"> <xsl:with-param name="first" select="$first - 1"/> <xsl:with-param name="final" select="$final"/> </xsl:call-template> </xsl:if> </xsl:template>
<xsl:template name="sing-verse-starting-with-number"> <xsl:param name="n"/>
<xsl:call-template name="sing-line-containing-number"> <xsl:with-param name="n" select="$n"/> </xsl:call-template>
<xsl:call-template name="sing-line-containing-number"> <xsl:with-param name="n" select="$n"/> <xsl:with-param name="suffix"/> </xsl:call-template>
<xsl:text>Take one down, pass it around </xsl:text>
<xsl:call-template name="sing-line-containing-number"> <xsl:with-param name="n" select="$n - 1"/> </xsl:call-template>
<xsl:text> </xsl:text> </xsl:template>
<xsl:template name="sing-line-containing-number"> <xsl:param name="n"/> <xsl:param name="suffix"> on the wall</xsl:param>
<xsl:value-of select="$n"/> <xsl:text> bottle</xsl:text> <xsl:if test="$n != 1">s</xsl:if> <xsl:text> of beer</xsl:text> <xsl:value-of select="$suffix"/> <xsl:text> </xsl:text> </xsl:template>
</xsl:stylesheet></lang>
Yorick
Looped version
<lang yorick>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;
}</lang>
Vectorized version
<lang yorick>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;</lang>
Z80 Assembly
See 99 Bottles of Beer/Assembly
zkl
<lang 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"
}</lang>
- 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.
- Programming Tasks
- Solutions by Programming Task
- 0815
- 360 Assembly
- 6502 Assembly
- 6800 Assembly
- 8th
- ABAP
- ACL2
- ActionScript
- Ada
- Aime
- ALGOL 68
- AmigaE
- Apache Ant
- APL
- App Inventor
- AppleScript
- Arbre
- Argile
- ARM Assembly
- ATS
- AutoHotkey
- AutoIt
- AWK
- Axe
- Babel
- BASIC
- FBSL
- Integer BASIC
- Liberty BASIC
- OxygenBasic
- PureBasic
- REALbasic
- Run BASIC
- TI-83 BASIC
- TI-89 BASIC
- Visual Basic
- Batch File
- Battlestar
- Befunge
- Bracmat
- Brainf***
- Brat
- C
- C++
- C sharp
- Clay
- Chapel
- Chef
- CLIPS
- Clojure
- COBOL
- CoffeeScript
- ColdFusion
- Common Lisp
- Component Pascal
- D
- Dart
- Delphi
- Déjà Vu
- Dylan
- E
- ECL
- EGL
- Eiffel
- Ela
- Elixir
- Erlang
- Euphoria
- Extended BrainF***
- F Sharp
- Factor
- Falcon
- FALSE
- Ferite
- Fexl
- Forth
- Fortran
- Frege
- Friendly interactive shell
- Frink
- FunL
- GAP
- Gnuplot
- Go
- Go!
- Gosu
- Golfscript
- Groovy
- GUISS
- GW-BASIC
- Haskell
- Haxe
- HicEst
- HQ9+
- Icon
- Unicon
- IDL
- Idris
- Inform 6
- Inform 7
- Intercal
- Io
- Ioke
- J
- Java
- Swing
- AWT
- JavaScript
- Joy
- Jq
- Julia
- K
- Kotlin
- LabVIEW
- Lasso
- LaTeX
- Lang5
- Lhogho
- LiveCode
- Lisp
- LLVM
- Logo
- Logtalk
- LOLCODE
- Lua
- Lucid
- M4
- Make
- Jot
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Maxima
- MAXScript
- Mirah
- MIRC Scripting Language
- MLite
- ML/I
- Modula-2
- Modula-3
- Monkey
- MOO
- MoonScript
- MUMPS
- NASL
- Nemerle
- NetRexx
- NewLISP
- Nial
- Nim
- OASYS
- OASYS Assembler
- Objective-C
- Oberon-2
- OCaml
- Octave
- Oforth
- OOC
- OoRexx
- OpenEdge/Progress
- Order
- Oxygene
- Oz
- PARI/GP
- Pascal
- Perl
- Perl 6
- Phix
- PHL
- PHP
- PicoLisp
- Piet
- Pike
- PIR
- PlainTeX
- Pop11
- PostScript
- PowerShell
- ProDOS
- Prolog
- Python
- Qore
- Quill
- R
- Ra
- Racket
- RapidQ
- Rascal
- Raven
- REBOL
- Retro
- REXX
- RPL/2
- Ruby
- Rust
- Sather
- Scala
- Scheme
- Scratch
- Sed
- Seed7
- Shiny
- Sidef
- Slate
- Smalltalk
- SNOBOL4
- SNUSP
- Sparkling
- SQL
- Squirrel
- Standard ML
- Suneido
- Swift
- Tcl
- Thyrd
- TIScript
- TorqueScript
- TUSCRIPT
- TXR
- UBasic/4tH
- UNIX Shell
- UnixPipes
- Ursala
- V
- Vala
- VBA
- VBScript
- Visual Prolog
- Vox
- Wart
- Whenever
- Wortel
- Wrapl
- Wren
- X86 Assembly
- XEec
- Xojo
- XPL0
- XSLT
- Yorick
- Z80 Assembly
- Zkl