99 Bottles of Beer

99 Bottles of Beer
You are encouraged to solve this task according to the task description, using any language you may know.

Task

Display the complete lyrics for the song: 99 bottles of beer on the wall.

The beersong

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).

Works with: ALGOL 68 version Standard - no extensions to language used

Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386

main:(FOR bottles FROM 99 TO 1 BY-1 DOprintf(($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)

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!

// Print two digits, use the value in afun printnum b = a loopbreak(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

// 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 >= 2continue(c >=2)

A much more “economic” version that tries to avoid repetition at the price of complicated conditional jumps and self-modifying code that takes up more place than the actual strings themselves.
Output is the same as in the straightforward version.

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.

int main(void){unsignedint 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;}

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

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:

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:

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:

//>,_//Beer Song>,_#include <iostream>usingnamespace 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;elsecout<<((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++);}return0;}//// by barrym 2011-05-01// no bottles were harmed in the// making of this program!!!

class Program{staticvoid 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();}}}}

privatestaticvoid beer(int bottles){for(int i = bottles; i >0; i--){if(i >1){ Console.Write("{0}\n{1}\n{2}\n{3}\n\n", i +" bottles of beer on the wall", i +" bottles of beer","Take one down, pass it around",(i -1)+" bottles of beer on the wall");}else Console.Write("{0}\n{1}\n{2}\n{3}\n\n", i +" bottle of beer on the wall", i +" bottle of beer","Take one down, pass it around",(i -1)+" bottles of beer on the wall....");}}}

Output:

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

/* 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 ";

// 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);

proceduredivision.100-mainsection.100-setup.performvarying counter from99by -1until no-bottles-leftperform100-show-numberdisplay" of beer on the wall"perform100-show-numberdisplay" of beer"display"Take "withnoadvancingif one-bottle-leftdisplay"it "withnoadvancingelsedisplay"one "withnoadvancing end-ifdisplay"down and pass it round"subtract1from counter giving counterperform100-show-numberdisplay" of beer on the wall"add1to counter giving counterdisplayspace 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"stoprun.

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

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

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

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

import std.stdio, std.conv;

string bottles(insize_t num)pure{staticstring bottlesRecurse(insize_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!";}

Uses D template meta-programming and recursion to pre-generate the song lyrics and prints it at compile via pragma(msg,...)

module bottles;

template BeerSong(int Bottles){staticif(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);}}

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

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.`)}

output_lyrics-- Output the lyrics to 99-bottles-of-beer.local l_bottles:LINKED_LIST[INTEGER]docreate l_bottles.make across (1|..|99)as ic loop l_bottles.force(ic.item)end across l_bottles.new_cursor.reversedas 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>1then print (ic_bottles.item) print (" bottles of beer on the wall.%N%N")endend 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

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"

get = StringWriter new writeLine:(target bottleDescription):" of beer on the wall" writeLine:(target bottleDescription):" of beer" writeLine:"Take one down, pass it around" writeLine:((target -= 1) bottleDescription):" of beer on the wall". } ]. }

#symbol program =[ #var bottles := 99.

bottles bottleEnumerator run &each:printingLn.].

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

-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, 99bottles 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 ofbeer on the wall.~n~n").

sing_verse(Bottle)->receive{_,Verse}whenBottle==0->io:format(Verse);{N,Verse}whenBottle==N->io:format(Verse),sing_verse(Bottle-1)after3000->io:format("Verse not received - re-starting singer~n"),spawn_singer(Bottle),sing_verse(Bottle)end.

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

\ 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 ;

Forth Console Output

2 beers2 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.

subroutine show_bottles(this)implicitnone class(TBottles)::this! integer :: show_bottlescharacter(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)"

subroutine take_one_bottle(this)! bind(c, name='take_one_bottle')implicitnone class(TBottles)::this! integer :: take_one_bottlecharacter(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)"

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.

if (n == 0) println["Go to the store and buy some more, 99 bottles of beer on the wall."] else println["Take one down and pass it around, " + getBottleString[n-1, unit] + " on the wall.\n"]}

getBottleString[n, unit] := format[n*12 floz, unit, 6] + "s"

Sample randomized output:

0.019386 facecords of beer on the wall, 0.019386 facecords.
Take one down and pass it around, 0.019190 facecords on the wall.
36.750000 quarts of beer on the wall, 36.750000 quarts.
Take one down and pass it around, 36.375000 quarts on the wall.
581539.650545 brminims of beer on the wall, 581539.650545 brminims.
Take one down and pass it around, 575544.396416 brminims on the wall.
10.377148 scotsoatlippys of beer on the wall, 10.377148 scotsoatlippys.
Take one down and pass it around, 10.269053 scotsoatlippys on the wall.
7.416004 cangallons of beer on the wall, 7.416004 cangallons.
Take one down and pass it around, 7.337941 cangallons on the wall.
3335.894135 dessertspoons of beer on the wall, 3335.894135 dessertspoons.
Take one down and pass it around, 3300.405899 dessertspoons on the wall.
0.233105 barrelbulks of beer on the wall, 0.233105 barrelbulks.
Take one down and pass it around, 0.230599 barrelbulks on the wall.
21.766118 magnums of beer on the wall, 21.766118 magnums.
Take one down and pass it around, 21.529530 magnums on the wall.
1092.000000 fluidounces of beer on the wall, 1092.000000 fluidounces.
Take one down and pass it around, 1080.000000 fluidounces on the wall.
...
12.000000 ponys of beer on the wall, 12.000000 ponys.
Take one down and pass it around, 0.000000 ponys on the wall.
0.000000 brfluidounces of beer on the wall, 0.000000 brfluidounces.
Go to the store and buy some more, 99 bottles of beer on the wall.

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')

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

-- -- 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 =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"

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

Beer Hall is a room.

The plural of bottle of beer is bottles of beer. A bottle of beer is a kind of thing.

The wall is a scenery supporter in Beer Hall. 99 bottles of beer are on the wall.

When play begins: while something is on the wall: say "[what's on the wall] on the wall[line break]"; say "[what's on the wall][line break]"; say "Take one down, pass it around[line break]"; remove a random thing on the wall from play; say "[what's on the wall] on the wall[paragraph break]"; end the story.

To say what's on the wall: if more than one thing is on the wall, say list of things on the wall; otherwise say "[number of things on the wall in words] bottle[s] of beer".

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

publicstaticvoid 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");elseif(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");elseSystem.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);}}}

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.

public Beer(){ x=99; take=newJButton("Take one down, pass it around"); text=newJTextArea(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(newBorderLayout());//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}

publicvoid actionPerformed(ActionEvent arg0){if(arg0.getSource()== take){//if they clicked the buttonJOptionPane.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}}}

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

Object Oriented

function Bottles(count){this.count= count ||99;}

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

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!")}

\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}

\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}

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,N2isN-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).

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

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.

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.

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.

% file: beer.m% author:% Fergus Henderson <[email protected]> Thursday 9th November 1995% Re-written with new syntax standard library calls:% Paul Bone <[email protected]> 2015-11-20%% This beer song is more idiomatic Mercury than the original, I feel bad% saying that since Fergus is a founder of the language.

.data lyrica: .asciiz " bottles of beer on the wall, " lyricb: " bottles of beer.\nTake one down and pass it around, " lyricc: " bottles of beer on the wall. \n\n"

#normally, I don't like going past 80 columns, but that was done here. # there's an argument to be had for breaking this up. I chose not to # for simpler instructions. final_lyrics: "1 bottle of beer on the wall, 1 bottle of beer.\nTake one down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall."

.text #lw $a0,accumulator #load address of accumulator into $a0 (or is it getting val?) li $a1,99 #set the inital value of the counter to 99

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

mlite -f 99bob.m 2

Which, having specified 2 bottles, gives

2 bottles of beer on the wall
2 bottles of beer
take one down and pass it round
1 bottle of beer on the wall
1 bottle of beer on the wall
1 bottle of beer
take it down and pass it round
no bottles of beer on the wall
no bottles of beer on the wall
no bottles of beer
go to the store and buy some more
99 bottles of beer on the wall

' 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)

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'

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

for bn in countdown(99, 1): var cur = GetBottleNumber(bn) echo(cur, " on the wall, ", cur, ".") echo("Take one down and pass it around, ", GetBottleNumber(bn-1), " on the wall.\n")

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

other:

from strutils import format

for i in countdown(99, 1): case i of 3..99: echo format("""$1 bottles of beer on the wall$1 bottles of beerTake 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 beerTake 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 beerTake one down, pass it aroundNo more bottles of beer on the wall""", i) else: discard

for n =99downto1doPrintf.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

99 bottles of beer on the wall. 99 bottles of beer.
Take one down. Pass it around.
98 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.
0 bottles of beer on the wall.

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

#include "order/interpreter.h"

#define GEN_phrase(N_bottles, N_minus_1_bottles) \ N_bottles of beer on the wall, \ N_bottles of beer, take one down, pass it around, \ N_minus_1_bottles of beer on the wall.

declarefun{Bottles N}if N == 1 then"1 bottle"else N#" bottles"endendinfor 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

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")

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

Correct grammar and nice spacing in modern perl:

use 5.10.0;

$num=99;while($num>0){my$s="s"unless($num==1); say "$num bottle$s of beer on the wall, $num bottle$s of beer";$num--;my$s="s"unless($num==1);$num="No more"if($num==0); say "Take one down, pass it around, $num bottle$s of beer on the wall\n"}

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

#| 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"}

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

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

<?phpfor($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):"");}

while($bottles>0){printf(ngettext('%d bottle','%d bottles',$bottles)." of beer on the wall\n",$bottles);//X bottles of beer on the wallprintf(ngettext('%d bottle','%d bottles',$bottles)." of beer\n",$bottles);//X bottles of beerprintf("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

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

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)

#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="")

#alternativecat(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'))

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

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.

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:

/*REXX program displays lyrics to the song "99 Bottles of Beer on the Wall". */parsearg N .; if N==''| N==","then N=99/*let number of bottles be given. */

do j=N by -1to1/*start the countdown and singdown*/say j 'bottle's(j)"of beer on the wall,"/*sing the number bottles of beer.*/say j 'bottle's(j)"of beer."/* ··· and the song's refrain.*/say'Take one down, pass it around,'/*take a beer bottle and share it.*/ m=j-1/*M: number of bottles we have now*/if m==0then m='no'/*use "no" instead of numeric 0.*/say m 'bottle's(m)"of beer on the wall."/*sing the beer bottle inventory. */say/*a blank line between the verses.*/end/*j*//*Not quite 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,'/*obtain replenishment of the beer*/say N 'bottles of beer on the wall.'/*all is well in the ole tavern. */exit/*we're all done and also sloshed.*//*──────────────────────────────────────────────────────────────────────────────────────*/s: ifarg(1)=1thenreturn''; return's'/*a simple pluralizer function. */

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

99 bottles of beer on the wall,
99 bottles of beer.
Take one down, pass it around,
98 bottles of beer on the wall.
98 bottles of beer on the wall,
98 bottles of beer.
Take one down, pass it around,
97 bottles of beer on the wall.
97 bottles of beer on the wall,
97 bottles of beer.
Take one down, pass it around,
96 bottles of beer on the wall.
∙
∙
∙
2 bottles of beer on the wall,
2 bottles of beer.
Take one down, pass it around,
1 bottle of beer on the wall.
1 bottle of beer on the wall,
1 bottle of beer.
Take one down, pass it around,
no bottles of beer on the wall.
No more bottles of beer on the wall,
no more bottles of beer.
Go to the store and buy some more,
99 bottles of beer on the wall.

for i = 99 to 0 step -1switch ion 0see "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."on 1see "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.

"othersee string(i) + " bottles of beer on the wall, " + string(i) + " bottles of beer.Take one down and pass it around, " + string(i-1) + " bottles of beer on the wall.

"offnext

Output:

99 bottles of beer on the wall,
99 bottles of beer.
Take one down, pass it around,
98 bottles 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.

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 == 1if i >1puts"#{i-1} bottle#{plural} of beer on the wall!"putselseputs"No more bottles of beer on the wall!"endend

99.downto(0)do|remaining|puts"#{bottles(remaining,true).capitalize}, #{bottles(remaining)}."if remaining==0print"Go to the store and buy some more" remaining=100elseprint"Take one down, pass it around"endputs", #{bottles(remaining-1,true)}.\n\n"end

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

s/.*/99 bottles of beer on the wall/h: bs/^0///^0/qs/^1 bottles/1 bottle/ps/on.*//ps/.*/Take one down, pass it around/pg/^.[1-9]/{hs/^.//y/123456789/012345678/xs/^\(.\).*$/\1/Gs/\n//hbb}y/0123456789/9012345678/hbb

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;

!bottles:(Integer num)[num.String+=if num=1[" bottle"]else[" bottles"]]99.to1[ print( bottles(idx)" of beer on the wall\n" bottles(idx)" of beer\n""Take one down, pass it around\n" bottles(idx-1)" of beer on the wall\n")]

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

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

i = 99while (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') }

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

@(next :list @(mapcar* (fun tostring) (range 99 -1 -1)))@(collect)@number@ (trailer)@number_less_1@ (cases)@ (bind number "1")@ (output)1 bottle of beer one the wall1 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

0010 REM main0011 IF I>2 THEN GOTO 200012 IF I=2 THEN GOTO 300013 IF I=1 THEN GOTO 400014 GOTO 50

0020 REM if greater than two0021 PRINT I;" Bottles of beer on the wall, ";I;" bottles of beer."0022 LET I=I-10023 PRINT "Take one down and pass it around, ";0024 PRINT I;" bottles of beer on the wall."0025 GOTO 10

0030 REM if equals two0031 PRINT I;" Bottles of beer on the wall, ";I;" bottles of beer."0032 LET I=I-10033 PRINT "Take one down and pass it around, ";0034 PRINT I;" bottle of beer on the wall."0035 GOTO 10

0040 REM if equals one0041 PRINT I;" Bottle of beer on the wall, ";I;" bottle of beer."0042 LET I=I-10043 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 exit0051 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."

for (i in 99...0) { System.print("%(i) bottles of beer on the wall,") System.print("%(i) bottles of beer,") System.print("Take one down, pass it around,") System.print("%(i - 1) bottles of beer on the wall.\n")}

<!-- Main procedure --><xsl:templatematch="/"><!-- Default parameters are used --><xsl:call-templatename="sing-all-verses-in-range"/></xsl:template>

<!-- Calls sing-verse-starting-with-number over each value in a range. --><xsl:templatename="sing-all-verses-in-range"><!-- Default parameters: From 99 through 1 --><xsl:paramname="first"select="99"/><xsl:paramname="final"select="1"/>

<!-- "($n - 1) bottles of beer on the wall" --><xsl:call-templatename="sing-line-containing-number"><!-- End verse with one less bottle --><xsl:with-paramname="n"select="$n - 1"/></xsl:call-template>

<xsl:text>&#10;</xsl:text></xsl:template>

<!-- Outputs "[number] bottle[s] of beer[ on the wall]" --><xsl:templatename="sing-line-containing-number"><xsl:paramname="n"/><!-- If no suffix is specified, use " on the wall" --><xsl:paramname="suffix"> on the wall</xsl:param>

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

Output:

99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.
...
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.