99 Bottles of Beer

You are encouraged to 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 beer song

The lyrics follow this form:

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

... and so on, until reaching 0.

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





Related tasks





See also







See 99 Bottles of Beer/EsoLang

See 99 Bottles of Beer/Assembly

See 99 Bottles of Beer/Assembly

See 99 Bottles of Beer/Assembly

See 99 Bottles of Beer/Assembly



\ 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



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 .

or (With ABAP 7.40)

REPORT YCL_99_BOTTLES .



DATA it_99_bottles TYPE TABLE OF string WITH EMPTY KEY .

DATA ( cr_lf ) = cl_abap_char_utilities => cr_lf .

it_99_bottles = VALUE # (

FOR i = 99 THEN i - 1 UNTIL i = 0 ( COND string ( LET lv = ( i - 1 )

lr = i && | bottles of beer on the wall|

&& cr_lf

&& i && | bottles of beer|

&& cr_lf

&& |Take one down , pass it around|

&& cr_lf

&& lv && | bottles of beer on the wall|

&& cr_lf IN WHEN 1 = 1 THEN lr )

)

) .

cl_demo_output => write ( it_99_bottles ) .

cl_demo_output => display ( ) .



See 99 Bottles of Beer/Lisp

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

" ) ;

}

Simple version [ edit ]

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;

Concurrent version [ edit ]

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

with Ada. Text_Io ; use Ada. Text_Io ;



procedure Tasking_99_Bottles is

subtype Num_Bottles is Natural range 1 .. 99 ;

task Print is

entry Set ( Num_Bottles ) ;

end Print;

task body Print is

Num : Natural;

begin

for I in reverse Num_Bottles' range loop

select

accept

Set ( I ) do -- Rendezvous with Counter task I

Num := I;

end Set;

Put_Line ( Integer'Image ( Num ) & " bottles of beer on the wall" ) ;

Put_Line ( Integer'Image ( Num ) & " bottles of beer" ) ;

Put_Line ( "Take one down, pass it around" ) ;

Put_Line ( Integer'Image ( Num - 1 ) & " bottles of beer on the wall" ) ;

New_Line;

or terminate ; -- end when all Counter tasks have completed

end select ;

end loop ;

end Print;

task type Counter ( I : Num_Bottles ) ;

task body Counter is

begin

Print. Set ( I ) ;

end Counter;

type Task_Access is access Counter;



Task_List : array ( Num_Bottles ) of Task_Access;



begin

for I in Task_List' range loop -- Create 99 Counter tasks

Task_List ( I ) := new Counter ( I ) ;

end loop ;

end Tasking_99_Bottles;

integer bottles;



bottles = 99;



do {

o_(bottles, " bottles of beer on the wall

");

o_(bottles, " bottles of beer

");

o_("Take one down, pass it around

");

o_(bottles -= 1, " bottles of beer on the wall



");

} while (bottles);



# 99 Bottles of Beer on the Wall

# in Algae

# bottles.A

for (i in 99:1:1) {

if (i != 1) {

printf("%d bottles of beer on the wall

";i);

printf("%d bottles of beer...

";i);

printf("you take on down and pass it around...

");

if ( i == 2) {

printf("%d bottles of beer on the wall



";i-1);

else

printf("%d bottles of beer on the wall



";i-1);

}

else

printf("1 bottle of beer on the wall

");

printf("1 bottle of beer...

");

printf("you take on down and pass it around..

");

printf("no more bottles of beer on the wall!



");

}

}



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

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

main : (

FOR bottles FROM 99 TO 1 BY - 1 DO

printf ( ( $z - d " bottles of beer on the wall" l$ , bottles ) ) ;

printf ( ( $z - d " bottles of beer" l$ , bottles ) ) ;

printf ( ( $ "Take one down, pass it around" l$ ) ) ;

printf ( ( $z - d " bottles of beer on the wall" ll$ , bottles - 1 ) )

OD

)



BEGIN



COMMENT PRINT LYRICS TO "99 BOTTLES OF BEER ON THE WALL";



STRING FUNCTION BOTTLE(N); % GIVE CORRECT GRAMMATICAL FORM %

INTEGER N;

BEGIN

IF N = 1 THEN

BOTTLE := " BOTTLE"

ELSE

BOTTLE := " BOTTLES";

END;



INTEGER N;



N := 99;

WHILE N > 0 DO

BEGIN

WRITE(N, BOTTLE(N), " OF BEER ON THE WALL,");

WRITEON(N, BOTTLE(N), " OF BEER");

WRITE("TAKE ONE DOWN AND PASS IT AROUND, ");

N := N - 1;

IF N = 0 THEN

WRITEON("NO MORE")

ELSE

WRITEON(N);

WRITEON(BOTTLE(N), " OF BEER ON THE WALL");

WRITE(" "); % BLANK LINE BETWEEN STANZAS %

END;

WRITE("THANKS FOR SINGING ALONG!");



END



PROC main()

DEF t: PTR TO CHAR,

s: PTR TO CHAR,

u: PTR TO CHAR, i, x

t := 'Take one down, pass it around

'

s := '\d bottle\s of beer\s

'

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

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

<?xml version = "1.0" ?>

<project name = "n bottles" default = "99_bottles" >



<!-- ant-contrib.sourceforge.net for arithmetic and if -->

<taskdef resource = "net/sf/antcontrib/antcontrib.properties" />



<!-- start count of bottles, you can set this with

e.g. ant -f 99.xml -Dcount=10 -->

<property name = "count" value = "99" />



<target name = "99_bottles" >

<antcall target = "bottle" >

<param name = "number" value = "${count}" />

</antcall >

</target >



<target name = "bottle" >

<echo message = "${number} bottles of beer on the wall" />

<echo message = "${number} bottles of beer" />

<echo message = "Take one down, pass it around" />



<math result = "result" operand1 = "${number}" operation = "-" operand2 = "1" datatype = "int" />



<echo message = "${result} bottles of beer on the wall" />



<if >

<not > <equals arg1 = "${result}" arg2 = "0" /> </not >

<then >

<antcall target = "bottleiterate" >

<param name = "number" value = "${result}" />

</antcall >

</then >

</if >

</target >



<target name = "bottleiterate" >

<antcall target = "bottle" >

<param name = "number" value = "${number}" />

</antcall >

</target >



</project >



for(Integer i = 99; i=0; i--){

system.debug(i + ' bottles of beer on the wall');

system.debug('

');

system.debug(i + ' bottles of beer on the wall');

system.debug(i + ' bottles of beer');

system.debug('take one down, pass it around');

}



Works with: Dyalog APL





Classic version [ edit ]

Translation of: J

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

One line version [ edit ]

⍪{(⍕⍵),' bottles of beer on the wall, take one down and pass it around, ',(⍕⍵-1),' bottles of beer on the wall'}¨⌽⍳99

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

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

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>

Iteration [ edit ]

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





Declaration [ edit ]

-- BRIEF -----------------------------------------------------------------------

on run

set localisations to ¬

{ "on the wall" , ¬

"Take one down, pass it around" , ¬

"Better go to the store to buy some more" , "bottle" }



intercalate ( "



" , ¬

( map ( curry ( incantation ) 's |λ| ( localisations ) , enumFromTo ( 99 , 0 ) ) ) )

end run





-- DECLARATIVE -----------------------------------------------------------------



-- incantation :: [String] -> Int -> String

on incantation ( xs, n )

script asset

on |λ| ( n )

unwords ( { ( n as string ) , item - 1 of xs & cond ( n ≠ 1 , "s" , "" ) } )

end |λ|

end script



script store

on |λ| ( n )

unwords ( { asset ' s |λ| ( n ) , item 1 of xs } )

end |λ|

end script



set { distribute, solve } to items 2 thru 3 of xs

if n > 0 then

unlines ( { store ' s |λ| ( n ) , asset ' s |λ| ( n ) , distribute, store ' s |λ| ( n - 1 ) } )

else

solve

end if

end incantation





-- GENERICALLY DYSFUNCTIONAL ---------------------------------------------------



-- cond :: Bool -> a -> a -> a

on cond ( bln, f, g )

if bln then

f

else

g

end if

end cond



-- curry :: (Script|Handler) -> Script

on curry ( f )

script

on |λ| ( a )

script

on |λ| ( b )

|λ| ( a, b ) of mReturn ( f )

end |λ|

end script

end |λ|

end script

end curry



-- enumFromTo :: Int -> Int -> [Int]

on enumFromTo ( m, n )

if m > n then

set d to - 1

else

set d to 1

end if

set lst to { }

repeat with i from m to n by d

set end of lst to i

end repeat

return lst

end enumFromTo



-- intercalate :: Text -> [Text] -> Text

on intercalate ( strText, lstText )

set { dlm, my text item delimiters } to { my text item delimiters , strText }

set strJoined to lstText as text

set my text item delimiters to dlm

return strJoined

end intercalate



-- map :: (a -> b) -> [a] -> [b]

on map ( f, xs )

tell mReturn ( f )

set lng to length of xs

set lst to { }

repeat with i from 1 to lng

set end of lst to |λ| ( item i of xs, i, xs )

end repeat

return lst

end tell

end map



-- Lift 2nd class handler function into 1st class script wrapper

-- mReturn :: Handler -> Script

on mReturn ( f )

if class of f is script then

f

else

script

property |λ| : f

end script

end if

end mReturn



-- unlines :: [String] -> String

on unlines ( xs )

intercalate ( linefeed, xs )

end unlines



-- unwords :: [String] -> String

on unwords ( xs )

intercalate ( space , xs )

end unwords



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





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 "

"

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

}

See 99 Bottles of Beer/Assembly

As ArnoldC does not feature string concatenation, the numbers of bottles and the rest of the parts of the lyrics are printed on separate lines.

IT'S SHOWTIME

HEY CHRISTMAS TREE is0

YOU SET US UP @NO PROBLEMO

HEY CHRISTMAS TREE bottles

YOU SET US UP 99

STICK AROUND is0

TALK TO THE HAND bottles

TALK TO THE HAND " bottles of beer on the wall"

TALK TO THE HAND bottles

TALK TO THE HAND " bottles of beer"

TALK TO THE HAND "Take one down, pass it around"

GET TO THE CHOPPER bottles

HERE IS MY INVITATION bottles

GET DOWN 1

ENOUGH TALK

TALK TO THE HAND bottles

TALK TO THE HAND " bottles of beer on the wall"

GET TO THE CHOPPER is0

HERE IS MY INVITATION bottles

LET OFF SOME STEAM BENNET 0

ENOUGH TALK

CHILL

YOU HAVE BEEN TERMINATED

fun bottles ( n ) : match __args__:

( 0 ) => "No more bottles"

( 1 ) => "1 bottle"

( _ ) => "$n bottles"



for n in 99 ..- 1 .. 1 :

print @ format """

{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



"""

//

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

See 99 Bottles of Beer/Shell

See 99 Bottles of Beer/Shell

Regular version [ edit ]

If you don't want so many beers, here you can specify the starting amount.

For example, just a sixpack:

# usage: gawk -v i=6 -f beersong.awk



function bb ( n ) {

b = " bottles of beer"

if ( n == 1 ) { sub ( "s" , "" ,b ) }

if ( n == 0 ) { n= "No more" }

return n b

}



BEGIN {

if ( ! i ) { i = 99 }

ow = "on the wall"

td = "Take one down, pass it around."

print "The beersong:

"

while ( i > 0 ) {

printf ( "%s %s,

%s.

%s

%s %s.



" ,

bb ( i ) , ow, bb ( i ) , td, bb ( -- i ) , ow )

if ( i == 1 ) sub ( "one" , "it" , td )

}

print "Go to the store and buy some more!"

}

Output:

The beersong: 99 bottles of beer on the wall, 99 bottles of beer. Take one down, pass it around. 98 bottles of beer on the wall. ... 3 bottles of beer on the wall, 3 bottles of beer. Take one down, pass it around. 2 bottles of beer on the wall. 2 bottles of beer on the wall, 2 bottles of beer. Take one down, pass it around. 1 bottle of beer on the wall. 1 bottle of beer on the wall, 1 bottle of beer. Take it down, pass it around. No more bottles of beer on the wall. Go to the store and buy some more!

Bottled version [ edit ]

See 99-bottles-of-beer.net

Pauses are added to accommodate the small calculator screen so all of the text can be read.

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

-- beer.sp



{b " bottles of beer" <

bi { itoa << } <

bb { bi ! b << w << "

" << } <

w " on the wall" <

beer

{<-

{ iter 1 + dup

<- bb ! ->

bi ! b << "

" <<

"Take one down, pass it around

" <<

iter bb ! "

" << }

->

times}

< }



-- At the prompt, type 'N beer !' (no quotes), where N is the number of stanzas you desire

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic#BaCon

See 99 Bottles of Beer/Basic#Commodore_BASIC

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Basic

See 99 Bottles of Beer/Shell



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

"

const nl = "

"



// Reserve 1024 bytes in the .bss section

var x 1024



// Write two digits, based on the value in a

fun printnum

b = a

a >= 10

a /= 10

// modulo is in the d register after idiv

b = d

a += 48 // ASCII value for '0'

print ( chr ( a ) )

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

x = bottle

x += plural

x += ofbeer

x += wall

x += sep

print ( x )



// Retrieve and print the number

stack -> a

printnum ( )



// N, "bottles of beer.

Take one down and pass it around,"

x = bottle

x += plural

x += ofbeer

x += dotnl

x += takedown

print ( x )



// 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 + a blank line

x = ofbeer

x += wall

x += dotnl

x += nl

print ( x )



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

x = bottle

x += ofbeer

x += wall

x += sep

print ( x )



// "1"

a = 1

printnum ( )



// "bottle of beer. Take one down and pass it around,"

// "no more bottles of beer on the wall."

// Blank line

// "No more bottles of beer on the wall,"

// "no more bottles of beer."

// "Go to the store and buy some more,"

x = bottle

x += ofbeer

x += dotnl

x += takedown

x += l_no

x += more

x += wall

x += dotnl

x += nl

x += u_no

x += more

x += wall

x += sep

x += l_no

x += more

x += dotnl

x += store

print ( x )



// "99"

a = 99

printnum ( )



// "bottles of beer on the wall."

x = bottle

x += plural

x += ofbeer

x += wall

x += dotnl

print ( x )

end

end



// vim: set syntax=c ts=4 sw=4 et:



i = 99;

while ( 1 ) {

print i , " bottles of beer on the wall

";

print i , " bottles of beer

Take one down, pass it around

";

if (i == 2) {

break

}

print --i , " bottles of beer on the wall

";

}



print --i , " bottle of beer on the wall

";

print i , " bottle of beer on the wall

";

print i , " bottle of beer

Take it down, pass it around

no more bottles of beer on the wall

";

quit

Straightforward implementation, displaying the full lyrics given on [ http://99-bottles-of-beer.net/ ]



> NN p

> d#_8~2~(P~3~.~1~>{` bottles of beer on the wall, `{` bottles of beer.`q

d`.llaw eht no reeb fo selttob `{pLM` ,dnuora ti ssap dna nwod eno ekaT`N<

q`.llaw eht no reeb fo elttob ` {<

> NN >{` bottle of beer on the wall, `{` bottle of beer.`N q

pN `.llaw eht no reeb fo selttob erom on ,dnuora ti ssap dna nwod eno ekaT`<

>N`No more bottles of beer on the wall, no more bottles of beer.`N q

;`.llaw eht no reeb fo selttob 99 ,erom emos yub dna erots eht ot oG`<



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.

See 99 Bottles of Beer/EsoLang

Output is always in caps in the interpreter I use, but I typed the input in correct case to spare those whose interpreter might do lowercase and don't want to have this song shouted at them ;D.



DEFINE PROCEDURE ''MINUS'' [A,B]:

BLOCK 0: BEGIN

IF A < B, THEN:

QUIT BLOCK 0;

LOOP AT MOST A TIMES:

BLOCK 1: BEGIN

IF OUTPUT + B = A, THEN:

QUIT BLOCK 0;

OUTPUT <= OUTPUT + 1;

BLOCK 1: END;

BLOCK 0: END.



DEFINE PROCEDURE ''BOTTLES'' [COUNT]:

BLOCK 0: BEGIN

CELL(0) <= COUNT;

LOOP COUNT + 1 TIMES:



BLOCK 1: BEGIN



IF CELL(0) > 1, THEN:

PRINT[CELL(0), ' bottles of beer on the wall, ', CELL(0), ' bottles of beer. Take one down, pass it around, ', MINUS[CELL(0), 1], ' bottles of beer on the wall.'];



IF CELL(0) = 1, THEN:

PRINT['1 botle of beer on the wall, 1 bottle of beer. Take one down, pass it around, No more bottles of beer on the wall.'];



IF CELL(0) = 0, THEN:

PRINT['No more bottles of beer on the wall, no more bottles of beer. Go to the store, buy 99 more, 99 bottles of beer on the wall!'];



CELL(0) <= MINUS[CELL(0), 1];



BLOCK 1: END;

BLOCK 0: END.



BOTTLES[99];



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

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

Code to save to BottlesOfBeer.bra:

{BottlesOfBeer.bra



See http://99-bottles-of-beer.net/}



X=

new

= n upper nbottles lyrics

. 99:?n

& ( upper

= [email protected](!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+-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'(

,"BottlesOfBeer.bra",APP)

& lst'(r,"BottlesOfBeer.bra",APP)

& put$(str$("

new'" X ";

"),"BottlesOfBeer.bra",APP);



new'X;



See 99 Bottles of Beer/EsoLang

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

Translation of: C++

The simple solution [ edit ]

/*

* 99 Bottles, C, KISS (i.e. keep it simple and straightforward) version

*/



#include <stdio.h>



int main ( void )

{

int n ;



for ( n = 99 ; n > 2 ; n -- )

printf (

"%d bottles of beer on the wall, %d bottles of beer.

"

"Take one down and pass it around, %d bottles of beer on the wall.



" ,

n , n , n - 1 ) ;



printf (

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

" ) ;



return 0 ;

}

A recursive solution [ edit ]

#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

" , argc , argc == 1 ? ' \0 ' : 's' ) ;

printf ( "%d bottle%c of beer

" , argc , argc == 1 ? ' \0 ' : 's' ) ;

printf ( "Take one down, pass it around

" ) ;

printf ( "%d bottle%c of beer on the wall



" , argc - 1 , ( argc - 1 ) == 1 ? ' \0 ' : 's' ) ;

return argc - 1 ;

}

Code golf [ edit ]

#include <stdio.h>

main ( ) { _ = 100 ; while ( -- _ ) printf ( "%i bottle%s of beer in the wall,

%i bottle%"

"s of beer.

Take one down, pass it round,

%s%s



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

A preprocessor solution [ edit ]

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

#include <stdlib.h>

#include <stdio.h>



#define BOTTLE(nstr) nstr " bottles of beer"



#define WALL(nstr) BOTTLE(nstr) " on the wall"



#define PART1(nstr) WALL(nstr) "

" BOTTLE(nstr) \

"

Take one down, pass it around

"



#define PART2(nstr) WALL(nstr) "



"



#define MIDDLE(nstr) PART2(nstr) PART1(nstr)



#define SONG PART1("100") CD2 PART2("0")



#define CD2 CD3("9") CD3("8") CD3("7") CD3("6") CD3("5") \

CD3("4") CD3("3") CD3("2") CD3("1") CD4("")



#define CD3(pre) CD4(pre) MIDDLE(pre "0")



#define CD4(pre) MIDDLE(pre "9") MIDDLE(pre "8") MIDDLE(pre "7") \

MIDDLE(pre "6") MIDDLE(pre "5") MIDDLE(pre "4") MIDDLE(pre "3") \

MIDDLE(pre "2") MIDDLE(pre "1")



int main ( void )

{

( void ) printf ( SONG ) ;

return EXIT_SUCCESS ;

}

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

The bottled version [ edit ]

int b = 99 , u = 1 ;

#include<stdio.h>

char * d [ 16 ] , y [ ]

= "#:ottle/ of"

":eer_ a_Go<o5"

"st>y \x20 some6"

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

" :

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

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

}

}

}

}

C#6 Implementation [ edit ]

using System ;

class Program

{

static void Main ( )

{

Func < int , bool , string > f = ( x, y ) =>

$ "{(x == 0 ? " No more " : x.ToString())} bottle{(x == 1 ? " " : " s ")} of beer{(y ? " on the wall " : " ")} \r

" ;

for ( int i = 99 ; i > 0 ; i -- )

Console . WriteLine ( $ "{f(i, true)}{f(i, false)}Take one down, pass it around \r

{f(i - 1, true)}" ) ;

}

}

Linq Implementation [ edit ]

using System ;

using System.Linq ;



class Program

{

static void Main ( )

{

Enumerable . Range ( 1 , 99 ) . Reverse ( ) . Select ( x =>

$ "{x} bottle{(x == 1 ? " " : " s ")} of beer on the wall, {x} bottle{(x == 1 ? " " : " s ")} of beer!

" +

$ "Take {(x == 1 ? " it " : " one ")} down, pass it around, {(x == 1 ? " no more " : (x - 1).ToString())} bottles of beer on the wall!

"

) . ToList ( ) . ForEach ( x => Console . WriteLine ( x ) ) ;

}

}

Flexible Version [ edit ]

using System ;

using System.Globalization ;

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

}

}

}

Using Formatting [ edit ]

class songs

{

static void Main ( string [ ] args )

{

beer ( 3 ) ;

}



private static void beer ( int bottles )

{

for ( int i = bottles ; i > 0 ; i -- )

{

if ( i > 1 )

{

Console . Write ( "{0}

{1}

{2}

{3}



" ,

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}

{1}

{2}

{3}



" ,

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:

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

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

}

}

A Fun One [ edit ]

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

}

Using recursion [ edit ]

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

}

}

Using a While Loop [ edit ]

static void Main ( string [ ] args )

{

int numBottles = 99 ;

while ( numBottles > 0 )

{

if ( numBottles > 1 )

{

WriteLine ( "{0} bottles of beer on the wall, {0} bottles of beer." , numBottles ) ;

numBottles -= 1 ;

WriteLine ( "Take one down, pass it around, {0} bottles of beer on the wall.

" , numBottles ) ;

}

else

{

WriteLine ( "{0} bottle of beer on the wall, {0} bottle of beer." , numBottles ) ;

numBottles -= 1 ;

WriteLine ( "Take one down, pass it around, no more bottles of beer on the wall.

" ) ;

}

}

WriteLine ( "No more bottles of beer on the wall, no more bottles of beer." ) ;

WriteLine ( "Go to the store to buy some more, 99 bottles of beer on the wall..." ) ;

}

The simple solution [ edit ]

#include <iostream>

using std :: cout ;



int main ( )

{

for ( int bottles ( 99 ) ; bottles > 0 ; bottles - = 1 ) {

cout << bottles << " bottles of beer on the wall

"

<< bottles << " bottles of beer

"

<< "Take one down, pass it around

"

<< bottles - 1 << " bottles of beer on the wall



" ;

}

}

An object-oriented solution [ edit ]

WYSIWYG (with correct plurals and can buy some more):

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

A template metaprogramming solution [ edit ]

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

#include <iostream>



template < int max, int min > struct bottle_countdown

{

static const int middle = ( min + max ) / 2 ;

static void print ( )

{

bottle_countdown < max, middle + 1 > :: print ( ) ;

bottle_countdown < middle, min > :: print ( ) ;

}

} ;



template < int value > struct bottle_countdown < value, value >

{

static void print ( )

{

std :: cout << value << " bottles of beer on the wall

"

<< value << " bottles of beer

"

<< "Take one down, pass it around

"

<< value - 1 << " bottles of beer



" ;

}

} ;



int main ( )

{

bottle_countdown < 100 , 1 > :: print ( ) ;

return 0 ;

}

A function template solution [ edit ]

Function templates are a different approach to template metaprogramming:

#include <iostream>



template < unsigned int N > void bottles ( ) {

std :: cout << N << " bottles of beer on the wall

"

<< N << " bottles of beer

"

<< "Take one down, pass it around

"

<< N - 1 << " bottles of beer on the wall



" ;

bottles < N - 1 > ( ) ;

}



template <> void bottles < 0 > ( ) {

std :: cout << "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 ( ) {

bottles < 99 > ( ) ;

}



A Recursive solution [ edit ]

#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

" << endl ;

rec ( bottles ) ;

}

}



int main ( )

{

rec ( 99 ) ;

system ( "pause" ) ;

return 0 ;

}



A preprocessor solution [ edit ]

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

#include <iostream>

#include <ostream>



#define BOTTLE(nstr) nstr " bottles of beer"



#define WALL(nstr) BOTTLE(nstr) " on the wall"



#define PART1(nstr) WALL(nstr) "

" BOTTLE(nstr) \

"

Take one down, pass it around

"



#define PART2(nstr) WALL(nstr) "



"



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

}

Bottled Version [ edit ]

//>,_

//Beer Song>,_

#include <iostream>

using namespace std ;

int main ( ) { for ( int

b = - 1 ; b < 99 ; cout <<

'

' ) for ( int w = 0 ;

w < 3 ; cout << ".

" ) {

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

shared void ninetyNineBottles() {



String bottles(Integer count) =>

"``count == 0 then "No" else count``

bottle``count == 1 then "" else "s"``".normalized;



for(i in 99..1) {

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!

");

}

}

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

Works with: Chapel version 1.7.0



/***********************************************************************

* Chapel implementation of "99 bottles of beer"

*

* by Brad Chamberlain and Steve Deitz

* 07/13/2006 in Knoxville airport while waiting for flight home from

* HPLS workshop

* compiles and runs with chpl compiler version 1.7.0

* for more information, contact: [email protected]

*

*

* Notes:

* o as in all good parallel computations, boundary conditions

* constitute the vast bulk of complexity in this code (invite Brad to

* tell you about his zany boundary condition simplification scheme)

* o uses type inference for variables, arguments

* o relies on integer->string coercions

* o uses named argument passing (for documentation purposes only)

***********************************************************************/



// allow executable command-line specification of number of bottles

// (e.g., ./a.out -snumBottles=999999)

config const numBottles = 99;

const numVerses = numBottles+1;



// a domain to describe the space of lyrics

var LyricsSpace: domain(1) = {1..numVerses};



// array of lyrics

var Lyrics: [LyricsSpace] string;



// parallel computation of lyrics array

[verse in LyricsSpace] Lyrics(verse) = computeLyric(verse);



// as in any good parallel language, I/O to stdout is serialized.

// (Note that I/O to a file could be parallelized using a parallel

// prefix computation on the verse strings' lengths with file seeking)

writeln(Lyrics);





// HELPER FUNCTIONS:



proc computeLyric(verseNum) {

var bottleNum = numBottles - (verseNum - 1);

var nextBottle = (bottleNum + numVerses - 1)%numVerses;

return "

" // disguise space used to separate elements in array I/O

+ describeBottles(bottleNum, startOfVerse=true) + " on the wall, "

+ describeBottles(bottleNum) + ".

"

+ computeAction(bottleNum)

+ describeBottles(nextBottle) + " on the wall.

";

}





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, ";

}



See 99 Bottles of Beer/EsoLang



execute() {



// this class provides synchronization

// to get unique number of the bottle



class monitor giver {

int number = 100;

.get() { return --number; }

}

var g = new giver();



// start 99 concurrently worked threads

// each thread gets own number of the bottle and prints out his own verse

// (notice that the output lines from the threads will be mixed together)



{#[99]

int nr = g.get(); // get own number

host.println(nr," bottles of beer on the wall, "+nr+" bottles of beer");

host.print("Take one down, pass it around,");

if (nr > 1) {

host.println((nr-1)," bottles of beer on the wall.");

}

else {

host.println("no more bottles of beer on the wall.");

}

}

host.println("No more bottles of beer on the wall, no more bottles of beer.");

host.println("Go to the store and buy some more, 99 bottles of beer on the wall.");

return 0;

}



/* 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, bottle, "of beer

",

"take one down, pass it around

",

n, bottle, "of beer on the wall!

");



return s;

}



main() {

println(join("

", mapped(getRound, reversed(range(100)))));

}



fn bottle n:

n -> if = 0: 'no more bottles'

elif = 1: n + ' bottle'

else: n + ' bottles'



[99:0] -> * (@eager) fn i:

i -> bottle -> print (transform i: sentence-case) 'of beer on the wall,' @ 'of beer.'

if i = 0:

'Go to the store, buy some more, 99 bottles of beer on the wall.' -> print

else:

i - 1 -> bottle -> print 'Take one down and pass it around,' @ 'of beer on the wall.

'

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

( defn paragraph [ num ]

( str num " bottles of beer on the wall

"

num " bottles of beer

"

"Take one down, pass it around

"

( dec num ) " bottles of beer on the wall.

" ) )



( defn lyrics [ ]

( let [ numbers ( range 99 0 - 1 )

paragraphs ( map paragraph numbers ) ]

( clojure . string / join "

" paragraphs ) ) )





( print ( lyrics ) )

Or, using cl-format:

Translation of: Common Lisp

( clojure . pprint / cl - format

true

"~{~[~^~]~:*~D bottle~:P of beer on the wall~%~:*~D bottle~:P of beer

Take one down, pass it around,~%~D bottle~:P~:* of beer on the wall.~2%~}"

( range 99 0 - 1 ) )

Works with: OpenCOBOL version 1.1

Free form version.

identification division .

program-id . ninety-nine .

environment division .

data division .

working-storage section .

01 counter pic 99 .

88 no-bottles- left value 0 .

88 one-bottle- left value 1 .



01 parts-of-counter redefines counter .

05 tens pic 9 .

05 digits pic 9 .



01 after-ten- words .

05 filler pic x ( 7 ) value spaces .

05 filler pic x ( 7 ) value "Twenty" .

05 filler pic x ( 7 ) value "Thirty" .

05 filler pic x ( 7 ) value "Forty" .

05 filler pic x ( 7 ) value "Fifty" .

05 filler pic x ( 7 ) value "Sixty" .

05 filler pic x ( 7 ) value "Seventy" .

05 filler pic x ( 7 ) value "Eighty" .

05 filler pic x ( 7 ) value "Ninety" .

05 filler pic x ( 7 ) value spaces .



01 after-ten-array redefines after-ten- words .

05 atens occurs 10 times pic x ( 7 ) .



01 digit- words .

05 filler pic x ( 9 ) value "One" .

05 filler pic x ( 9 ) value "Two" .

05 filler pic x ( 9 ) value "Three" .

05 filler pic x ( 9 ) value "Four" .

05 filler pic x ( 9 ) value "Five" .

05 filler pic x ( 9 ) value "Six" .

05 filler pic x ( 9 ) value "Seven" .

05 filler pic x ( 9 ) value "Eight" .

05 filler pic x ( 9 ) value "Nine" .

05 filler pic x ( 9 ) value "Ten" .

05 filler pic x ( 9 ) value "Eleven" .

05 filler pic x ( 9 ) value "Twelve" .

05 filler pic x ( 9 ) value "Thirteen" .

05 filler pic x ( 9 ) value "Fourteen" .

05 filler pic x ( 9 ) value "Fifteen" .

05 filler pic x ( 9 ) value "Sixteen" .

05 filler pic x ( 9 ) value "Seventeen" .

05 filler pic x ( 9 ) value "Eighteen" .

05 filler pic x ( 9 ) value "Nineteen" .

05 filler pic x ( 9 ) value spaces .



01 digit-array redefines digit- words .

05 adigits occurs 20 times pic x ( 9 ) .



01 number-name pic x ( 15 ) .



procedure division .

100 - main section .

100 -setup .

perform varying counter from 99 by - 1 until no-bottles- left

perform 100 -show- number

display " of beer on the wall"

perform 100 -show- number

display " of beer"

display "Take " with no advancing

if one-bottle- left

display "it " with no advancing

else

display "one " with no advancing

end- if

display "down and pass it round"

subtract 1 from counter giving counter

perform 100 -show- number

display " of beer on the wall"

add 1 to counter giving counter

display space

end- perform .

display "No more bottles of beer on the wall"

display "No more bottles of beer"

display "Go to the store and buy some more"

display "Ninety Nine bottles of beer on the wall"

stop run .



100 -show- number .

if no-bottles- left

display "No more" with no advancing

else

if counter < 20

display function trim ( adigits ( counter ) ) with no advancing

else

if counter < 100

move spaces to number-name

string atens ( tens ) delimited by space , space delimited by size , adigits ( digits ) delimited by space into number-name

display function trim ( number-name ) with no advancing

end- if

end- if

end- if .

if one-bottle- left

display " bottle" with no advancing

else

display " bottles" with no advancing

end- if .



100 - end .

end- program .

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

identification division .

program-id . ninety-nine .

environment division .

data division .

working-storage section .

01 counter pic 99 .

88 no-bottles- left value 0 .

88 one-bottle- left value 1 .



01 parts-of-counter redefines counter .

05 tens pic 9 .

05 digits pic 9 .



01 after-ten- words .

05 filler pic x ( 7 ) value spaces .

05 filler pic x ( 7 ) value "Twenty" .

05 filler pic x ( 7 ) value "Thirty" .

05 filler pic x ( 7 ) value "Forty" .

05 filler pic x ( 7 ) value "Fifty" .

05 filler pic x ( 7 ) value "Sixty" .

05 filler pic x ( 7 ) value "Seventy" .

05 filler pic x ( 7 ) value "Eighty" .

05 filler pic x ( 7 ) value "Ninety" .

05 filler pic x ( 7 ) value spaces .



01 after-ten-array redefines after-ten- words .

05 atens occurs 10 times pic x ( 7 ) .



01 digit- words .

05 filler pic x ( 9 ) value "One" .

05 filler pic x ( 9 ) value "Two" .

05 filler pic x ( 9 ) value "Three" .

05 filler pic x ( 9 ) value "Four" .

05 filler pic x ( 9 ) value "Five" .

05 filler pic x ( 9 ) value "Six" .

05 filler pic x ( 9 ) value "Seven" .

05 filler pic x ( 9 ) value "Eight" .

05 filler pic x ( 9 ) value "Nine" .

05 filler pic x ( 9 ) value "Ten" .

05 filler pic x ( 9 ) value "Eleven" .

05 filler pic x ( 9 ) value "Twelve" .

05 filler pic x ( 9 ) value "Thirteen" .

05 filler pic x ( 9 ) value "Fourteen" .

05 filler pic x ( 9 ) value "Fifteen" .

05 filler pic x ( 9 ) value "Sixteen" .

05 filler pic x ( 9 ) value "Seventeen" .

05 filler pic x ( 9 ) value "Eighteen" .

05 filler pic x ( 9 ) value "Nineteen" .

05 filler pic x ( 9 ) value spaces .



01 digit-array redefines digit- words .

05 adigits occurs 20 times pic x ( 9 ) .



01 number-name pic x ( 15 ) .



01 stringified pic x ( 30 ) .

01 outline pic x ( 50 ) .

01 other-numbers .

03 n pic 999 .

03 r pic 999 .



procedure division .

100 - main section .

100 -setup .

perform varying counter from 99 by - 1 until no-bottles- left

move spaces to outline

perform 100 -show- number

string stringified delimited by "|" , space , "of beer on the wall" into outline end-string

display outline end- display

move spaces to outline

string stringified delimited by "|" , space , "of beer" into outline end-string

display outline end- display

move spaces to outline

move "Take" to outline

if one-bottle- left

string outline delimited by space , space , "it" delimited by size , space , "|" into outline end-string

else

string outline delimited by space , space , "one" delimited by size , space , "|" into outline end-string

end- if

string outline delimited by "|" , "down and pass it round" delimited by size into outline end-string

display outline end- display

move spaces to outline

subtract 1 from counter giving counter end-subtract

perform 100 -show- number

string stringified delimited by "|" , space , "of beer on the wall" into outline end-string

display outline end- display

add 1 to counter giving counter end- add

display space end- display

end- perform .

display "No more bottles of beer on the wall"

display "No more bottles of beer"

display "Go to the store and buy some more"

display "Ninety-Nine bottles of beer on the wall"

stop run .



100 -show- number .

if no-bottles- left

move "No more|" to stringified

else

if counter < 20

string function trim ( adigits ( counter ) ) , "|" into stringified

else

if counter < 100

move spaces to number-name

string atens ( tens ) delimited by space , space delimited by size , adigits ( digits ) delimited by space into number-name end-string

move function trim ( number-name ) to stringified

divide counter by 10 giving n remainder r end- divide

if r not = zero

inspect stringified replacing first space by "-"

end- if

inspect stringified replacing first space by "|"

end- if

end- if

end- if .

if one-bottle- left

string stringified delimited by "|" , space , "bottle|" delimited by size into stringified end-string

else

string stringified delimited by "|" , space , "bottles|" delimited by size into stringified end-string

end- if .



100 - end .

end- program .

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

program-id . ninety-nine .

data division .

working-storage section .

01 cnt pic 99 .



procedure division .



perform varying cnt from 99 by - 1 until cnt < 1

display cnt " bottles of beer on the wall"

display cnt " bottles of beer"

display "Take one down, pass it around"

subtract 1 from cnt

display cnt " bottles of beer on the wall"

add 1 to cnt

display space

end- perform .



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



""" for n in [ 99 .. 1 ]



With completely different approach...

for j in [ 99 .. 1 ]

x= ''

x + = [ j , j - 1 , '

Take one down, pass it around

' , " bottles of beer" , ' on the wall

' ] [ i ] for i in [ 0 , 3 , 4 , 0 , 3 , 2 , 1 , 3 , 4 ]

console. log x. replace / ( 1 . + ) s / g , '$1'



or as a one liner...

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

or another completely different one liner

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

Classic tag based CFML [ edit ]

< cfoutput >

< cfloop index = "x" from = "99" to = "0" step = "-1" >

< cfset plur = iif ( x is 1 , "" , DE ( "s" ) ) >

#x# bottle #plur# of beer on the wall < br >

#x# bottle #plur# of beer < br >

Take one down, pass it around < br >

#iif(x is 1,DE("No more"),"x-1")# bottle#iif(x is 2,"",DE("s"))# of beer on the wall < br > < br >

</ cfloop >

</ cfoutput >

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

CFScript [ edit ]

< cfscript >

for (x=99; x gte 1; x--) {

plur = iif(x==1,'',DE('s'));

WriteOutput(" #x# bottle #plur# of beer on the wall < br > #x# bottle #plur# of beer < br > < br > < br > < br >

}

</ cfscript >

bottles = ' bottles '

remaining = 99

one_less_bottle = remaining

depluralize

comefrom drinking if one_less_bottle is 1

bottles = ' bottle '



drinking

comefrom if remaining is one_less_bottle

remaining bottles 'of beer on the wall'

remaining bottles 'of beer'

'Take one down, pass it around'

one_less_bottle = remaining - 1

one_less_bottle bottles 'of beer on the wall`n'

remaining = remaining - 1



comefrom if one_less_bottle is 0

'No more bottles of beer on the wall'

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 No more bottles of beer on the wall

See 99 Bottles of Beer/Lisp

See 99 Bottles of Beer/Pascal

99.downto(1) do |n|

puts "#{n} bottle#{n > 1 ? "s" : ""} of beer on the wall"

puts "#{n} bottle#{n > 1 ? "s" : ""} of beer"

puts "Take one down, pass it around"

puts "#{n-1} bottle#{n > 2 ? "s" : ""} of beer on the wall



" if n > 1

end

puts "No more bottles of beer on the wall"



Simple Solution [ edit ]

Works with: D version 2

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

import std. stdio ;



void main ( ) {

int bottles = 99 ;



while ( bottles > 1 ) {

writeln ( bottles , " bottles of beer on the wall," ) ;

writeln ( bottles , " bottles of beer." ) ;

writeln ( "Take one down, pass it around," ) ;

if ( -- bottles > 1 ) {

writeln ( bottles , " bottles of beer on the wall.

" ) ;

}

}

writeln ( "1 bottle of beer on the wall.

" ) ;



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

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

import std. stdio , std. conv ;



string bottles ( in size_t num ) pure {

static string bottlesRecurse ( in size_t num ) pure {

return num. text ~ " bottles of beer on the wall,

"

~ num. text ~ " bottles of beer!

"

~ "Take one down, pass it around,

"

~ ( num - 1 ) . text ~ " bottle" ~ ( ( num - 1 == 1 ) ? "" : "s" )

~ " of beer on the wall.



"

~ ( ( num > 2 )

? bottlesRecurse ( num - 1 )

: "1 bottle of beer on the wall,

"

~ "1 bottle of beer!

"

~ "Take one down, pass it around,

"

~ "No bottles of beer on the wall!



" ) ;

}



return bottlesRecurse ( num )

~ "Go to the store and buy some more...

"

~ num. text ~ " bottles of beer on the wall!" ;

}



pragma ( msg , 99 . bottles ) ;

void main ( ) { }

Template Meta-Programming Solution [ edit ]

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 )

{

static if ( Bottles == 1 )

{

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

" ;

}

else

{

enum BeerSong = Bottles. stringof ~ " bottles of beer on the wall

" ~

Bottles. stringof ~ " bottles of beer

take it down, pass it around

" ~

BeerSong ! ( Bottles - 1 ) ;

}

}



pragma ( msg , BeerSong ! 99 ) ;



void main ( ) { }



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

}

}

Works with: GNU dc

Works with: OpenBSD dc

[

dnrpr

dnlBP

lCP

1-dnrp

rd2r >L

]sL



[Take one down, pass it around

]sC

[ bottles of beer

]sB

[ bottles of beer on the wall]

99



lLx



dnrpsA

dnlBP

lCP

1-

dn[ bottle of beer on the wall]p

rdnrpsA

n[ bottle of beer

]P

[Take it down, pass it around

]P

[no more bottles of beer on the wall

]P

Similar to the program above, but without 'n' and 'r' commands. It prints the numbers on separate lines than the strings.

Works with: AT&T dc

[

plAP

plBP

lCP

1-dplAP

d2r >L

]sL



[Take one down, pass it around

]sC

[bottles of beer

]sB

[bottles of beer on the wall

]sA

99



lLx



plAP

plBP

lCP

1-

p

[bottle of beer on the wall

]P

p

[bottle of beer

]P

[Take it down, pass it around

]P

[no more bottles of beer on the wall

]P

See 99 Bottles of Beer/Pascal

Translation of: Swift

for i in 99..1 {

print("\(i) bottles of beer on the wall, \(i) bottles of beer.")

const next = if i == 1 {

"no"

} else {

(i - 1).toString()

}

print("Take one down and pass it around, \(next) bottles of beer on the wall.")

}

Module: bottles

define method bottles (n :: <integer>)

for (n from 99 to 1 by -1)

format-out("%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 - 1);

end

end method

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



;

;===============================================================================

========================

; Oringinal Author: Bob Welton ([email protected])

; Language: DIBOL or DBL

;

; Modified to work with DEC DIBOL-11

; by Bill Gunshannon

;===============================================================================

========================



RECORD MISC

NUMBOTTLES ,D2,99 ;Default # of bottles to 99



RECORD LINE1

ANUMBOTTLES, A2

, A32, " Bottles of Beer on the wall,"



RECORD LINE2

BNUMBOTTLES, A2

, A32, " Bottles of Beer,"



RECORD LINE3

CNUMBOTTLES, A2

, A32, " Bottles of Beer on the wall."



RECORD LINE4

DNUMBOTTLES, A2

, A32, " Bottle of Beer on the wall,"



RECORD LINE5

ENUMBOTTLES, A2

, A32, " Bottle of Beer,"











.PROC

XCALL FLAGS (0007000000,1) ;Suppress STOP message

OPEN (8,O:C,"TT:") ;Open the terminal/display

REPEAT

BEGIN

ANUMBOTTLES = NUMBOTTLES,'ZX'

WRITES (8,LINE1)

BNUMBOTTLES = NUMBOTTLES,'ZX'

WRITES (8,LINE2)

WRITES (8," Take one down, pass it around,")

DECR NUMBOTTLES ;Reduce # of bottles by 1

IF (NUMBOTTLES .LE. 1) EXITLOOP ;If just 1 bottle left, get out

CNUMBOTTLES = NUMBOTTLES,'ZX'

WRITES (8,LINE3)

WRITES (8," ")

END

DNUMBOTTLES = NUMBOTTLES,'ZX'

WRITES(8,LINE4)

WRITES (8," ")

ENUMBOTTLES = NUMBOTTLES,'ZX'

WRITES(8,LINE5)

WRITES (8," Take one down, pass it around,")

WRITES(8,"0 Bottles of Beer on the wall,")

WRITES(8,"0 Bottles of Beer,")

WRITES(8,"Go to the store and buy some more,")

WRITES(8,"99 Bottles of Beer on the wall,")



WRITES (8," ")

WRITES (8," ")

SLEEP 2

CLOSE 8

STOP

.END







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.

` )

}



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





import "prelude.eg"

import "io.ego"



using System

using IO



def print_rhyme =

[ 0 ->

print "better go to the store, and buy some more

"

| N ->

let _ = print N " bottles of beer on the wall

" in

let _ = print N " bottles of beer

" in

let _ = print "take one down, pass it around

" in

print_rhyme (N - 1) ]



def main = print_rhyme 99



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.

");

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



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



An alternative version written using the across-loop construct.



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





open list



beer 1 = "1 bottle of beer on the wall

1 bottle of beer

Take 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

"

++ show v

++" bottles of beer

Take one down, pass it around

"



map beer [99,98..0]

ELENA 5.0 :

import system'routines;

import extensions;

import extensions'routines;

import extensions'text;



extension bottleOp

{

bottleDescription()

= self.toPrintable() + (self != 1).iif(" bottles"," bottle");



bottleEnumerator() = new Variable(self).doWith:(n)

{

^ new Enumerator

{

bool next() = n > 0;



get() = new StringWriter()

.printLine(n.bottleDescription()," of beer on the wall")

.printLine(n.bottleDescription()," of beer")

.printLine("Take one down, pass it around")

.printLine((n.reduce:1).bottleDescription()," of beer on the wall");



reset() {}



enumerable() = __target;

}

};

}



public program()

{

var bottles := 99;



bottles.bottleEnumerator().forEach: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

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

( let ( ( i 99 ) )

( while ( > i 0 )

( princ- list i " bottles of beer on the wall" "

Take one down, pass it around" )

( setq i ( 1 - i ) ) ) )

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

Works with: Euphoria version 4.0.0



constant

bottles = "bottles" ,

bottle = "bottle"



procedure beers ( integer how_much )

sequence word1 = bottles , word2 = bottles

switch how_much do

case 2 then

word2 = bottle

case 1 then

word1 = bottle

word2 = bottle

end switch



printf ( 1 ,

"%d %s of beer on the wall

" &

"%d %s of beer

" &

"Take one down, and pass it around

" &

"%d %s of beer on the wall



" ,

{ how_much , word1 ,

how_much , word1 ,

how_much - 1 , word2 }

)

end procedure



for a = 99 to 1 by - 1 do

beers ( a )

end for







-- An alternate version



include std / console.e



sequence howmany = { "No more bottles" , "%d bottle" , "" , "s" }



for beer = 99 to 1 by - 1 do

display ( `

[ 1 ] bottles of beer on the wall ,

[ 1 ] bottles of beer.

Take one down , drink it right down ,

[ 2 ] [ 3 ] of beer.

` , { beer ,

sprintf ( howmany [ ( beer> 1 ) + 1 ] , beer - 1 ) ,

howmany [ ( beer> 2 ) + 3 ]

} )

end for





See 99 Bottles of Beer/EsoLang

#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 - 1 ) after

if n > 1 then

bottles ( n - 1 )

USING: io kernel make math math.parser math.ranges sequences ;



: bottle ( -- quot )

[

[

[

[ # " bottles of beer on the wall,

" % ]

[ # " bottles of beer.

" % ] bi

] keep

"Take one down, pass it around,

" %

1 - # " bottles of beer on the wall

" %

] " " make print

] ; inline



: last-verse ( -- )

"Go to the store and buy some more,"

"no more bottles of beer on the wall!" [ print ] [email protected] ;



: bottles ( n -- )

1 [a,b] bottle each last-verse ;



! Usage: 99 bottles

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

"

end

A more robust version to handle plural/not plural conditions

for i in [ 99 : 1 ]

plural = ( i ! = 1 ) ? 's' : ""

> @ "$i bottle$plural of beer on the wall"

> @ "$i bottle$plural of beer"

> "Take one down, pass it around"

> i - 1 , @ " bottle$plural of beer on the wall

"

end

See 99 Bottles of Beer/EsoLang

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

uses "console";



number bottles = 99;

boolean looping = true;

object counter = closure {

if (--bottles > 0) {

return true;

} else {

return false;

}

};



while (looping) {

Console.println("${bottles} bottles of beer on the wall,");

Console.println("${bottles} bottles of beer,");

Console.println("Take one down, pass it around,");



looping = counter.invoke();



Console.println("${bottles} bottles of beer on the wall.");



\suffix=(

eq n 1 "" "s")

\sing_count=(

put [n " bottle" (suffix n) " of beer"])

\sing_line1=(

sing_count n say " on the wall")

\sing_line2=(

sing_count n nl)

\sing==

(



le n 0 ();

sing_line1 n

sing_line2 n

say "Take one down, pass it around"



=(- n 1)

sing_line1 n

nl

sing n

)

sing 3



Output:

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

: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

Version 2: create a beer language and write the program

DECIMAL

: BOTTLES ( n -- )

DUP

CASE

1 OF ." One more bottle " DROP ENDOF

0 OF ." NO MORE bottles " DROP ENDOF

. ." bottles " \ DEFAULT CASE

ENDCASE ;



: , [CHAR] , EMIT SPACE 100 MS CR ;

: . [CHAR] . EMIT 300 MS CR CR CR ;



: OF ." of " ; : BEER ." beer " ;

: ON ." on " ; : THE ." the " ;

: WALL ." wall" ; : TAKE ." take " ;

: ONE ." one " ; : DOWN ." down, " ;

: PASS ." pass " ; : IT ." it " ;

: AROUND ." around" ;



: POPONE 1 SWAP CR ;

: DRINK POSTPONE DO ; IMMEDIATE

: ANOTHER S" -1 +LOOP" EVALUATE ; IMMEDIATE

: HOWMANY S" I " EVALUATE ; IMMEDIATE

: ONELESS S" I 1- " EVALUATE ; IMMEDIATE

: HANGOVER ." :-(" CR QUIT ;



: BEERS ( n -- ) \ Usage: 99 BEERS

POPONE

DRINK

HOWMANY BOTTLES OF BEER ON THE WALL ,

HOWMANY BOTTLES OF BEER ,

TAKE ONE DOWN PASS IT AROUND ,

ONELESS BOTTLES OF BEER ON THE WALL .

ANOTHER

HANGOVER ;

Forth Console Output

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

F90 version [ edit ]

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

MPI version [ edit ]

program bottlesMPI



implicit none



integer :: ierr ,rank,nproc



character ( len =* ) , parameter :: bwall = " on the wall" , &

bottles = "bottles of beer" , &

bottle = "bottle of beer" , &

take = "Take one down, pass it around" , &

form = "(I0, ' ', A)"



call mpi_init ( ierr )

call mpi_comm_size ( MPI_COMM_WORLD,nproc, ierr )

call mpi_comm_rank ( MPI_COMM_WORLD,rank,ierr )



if ( rank /= 1 ) then

write ( * , form ) rank, bottles // bwall

if ( rank > 0 ) write ( * , form ) rank, bottles

else

write ( * , form ) rank, bottle // bwall

write ( * , form ) rank, bottle

end if

if ( rank > 0 ) write ( * , * ) take



call mpi_finalize ( ierr )



end program bottlesMPI

Usage:

mpif90 filename.f90 mpiexec -np 99 a.out

Fortran 2003/2008 OOP version [ edit ]

Works with GNU gfortran 5.0.0 and Intel ifort 15.0.2



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



Translation of: Haskell

Works with: Frege version 3.21.586-g026e8d7

module Beer where



main = mapM_ (putStrLn . beer) [99, 98 .. 0]

beer 1 = "1 bottle of beer on the wall

1 bottle of beer

Take 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

"

++ show v

++ " bottles of beer

Take one down, pass it around

"

++ head (lines $ beer $ v-1) ++ "

"

to the Haskell, apart from adding the module declaration)

See 99 Bottles of Beer/Shell

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



units = array[units[volume]]

showApproximations[false]



for n = 99 to 0 step -1

{

unit = units.removeRandom[]

str = getBottleString[n, unit]



println["$str of beer on the wall, $str."]



if (n == 0)

println["Go to the store and buy some more, 99 bottles of beer on the wall."]

else

println["Take one down and pass it around, " + getBottleString[n-1, unit] + " on the wall.

"]

}



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.

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( [email protected](13 | 15) ) = suffix( alt(n%10), 'teen' )

number( 20 ) = 'twenty'

number( [email protected](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.

'

+ '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.

'

+ 'Take one down and pass it around, ' + bottles( n-1 )

+ ' of beer on the wall.

')



for i <- 99..0 by -1 do println( verse(i) )



include "ConsoleWindow"



dim as short i



for i = 99 to 1 step -1

print i; " bottles of beer on the wall,"

print i; " bottles of beer."

print

print "Take one down, pass it around,"

print i-1; " bottles of beer on the wall."

print

next



Implementation of the code '99 bottles of beer' written in Visual Basic. Code tested in Gambas 3.15.2

' Gambas module file



Public Const bottlesofbeer As String = " bottles of beer."

Public Const onthewall As String = " on the wall."

Public Const takeonedown As String = "Take one down, pass it around."

Public Const onebeer As String = "1 bottle of beer"



Public Sub Main ( )



Dim bottles As Byte



For bottles = 99 To 3 Step - 1

Print CStr ( bottles ) & bottlesofbeer & onthewall

Print CStr ( bottles ) & bottlesofbeer

Print takeonedown

Print CStr ( bottles - 1 ) & bottlesofbeer & onthewall

Print

Next



Print "2" & bottlesofbeer & onthewall

Print "2" & bottlesofbeer

Print takeonedown

Print onebeer & onthewall

Print



Print onebeer & onthewall

Print onebeer

Print takeonedown

Print "No more" & bottlesofbeer & onthewall

Print



Print "No" & bottlesofbeer & onthewall

Print "No" & bottlesofbeer

Print "Go to the store, buy some more."

Print "99" & bottlesofbeer & onthewall



End

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;

[ indent = 4 ]

def plural ( n : uint ) : string

return ( n == 1 ) ? "" : "s"

def no ( n : uint ) : string

return ( n == 0 ) ? "No" : n. to_string ( )

init

bottles : uint = 99 ;

do

print "%u bottle%s of beer on the wall" , bottles, plural ( bottles )

print "%u bottle%s of beer" , bottles, plural ( bottles )

print "Take one down, pass it around"

-- bottles

print "%s bottle%s of beer on the wall

" , no ( bottles ) , plural ( bottles )

while bottles != 0

Output:

prompt$ valac 99bottles.gs prompt$ ./99bottles | tail -10 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

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

No sense of humor [ edit ]

package main



import "fmt"



func main () {

bottles := func ( i int ) string {

switch i {

case 0 :

return "No more bottles"

case 1 :

return "1 bottle"

default :

return fmt . Sprintf ( "%d bottles" , i )

}

}



for i := 99 ; i > 0 ; i -- {

fmt . Printf ( "%s of beer on the wall

" , bottles ( i ))

fmt . Printf ( "%s of beer

" , bottles ( i ))

fmt . Printf ( "Take one down, pass it around

" )

fmt . Printf ( "%s of beer on the wall

" , bottles ( i - 1 ))

}

}

Typoglycemic [ edit ]

With code from RC tasks Number names, Knuth shuffle.

package main



import (

"fmt"

"math/rand"

"strings"

"time"

)



func main () {

rand . Seed ( time . Now () . UnixNano ())

for i := 99 ; i > 0 ; i -- {

fmt . Printf ( "%s %s %s

" ,

slur ( numberName ( i ), i ),

pluralizeFirst ( slur ( "bottle of" , i ), i ),

slur ( "beer on the wall" , i ))

fmt . Printf ( "%s %s %s

" ,

slur ( numberName ( i ), i ),

pluralizeFirst ( slur ( "bottle of" , i ), i ),

slur ( "beer" , i ))

fmt . Printf ( "%s %s %s

" ,

slur ( "take one" , i ),

slur ( "down" , i ),

slur ( "pass it around" , i ))

fmt . Printf ( "%s %s %s

" ,

slur ( numberName ( i - 1 ), i ),

pluralizeFirst ( slur ( "bottle of" , i ), i - 1 ),

slur ( "beer on the wall" , i ))

}

}



// adapted from Number names task

func numberName ( n int ) string {

switch {

case n < 0 :

case n < 20 :

return small [ n ]

case n < 100 :

t := tens [ n / 10 ]

s := n % 10

if s > 0 {

t += " " + small [ s ]

}

return t

}

return ""

}



var small = [] string { "no" , "one" , "two" , "three" , "four" , "five" , "six" ,

"seven" , "eight" , "nine" , "ten" , "eleven" , "twelve" , "thirteen" ,

"fourteen" , "fifteen" , "sixteen" , "seventeen" , "eighteen" , "nineteen" }

var tens = [] string { "ones" , "ten" , "twenty" , "thirty" , "forty" ,

"fifty" , "sixty" , "seventy" , "eighty" , "ninety" }



// pluralize first word of s by adding an s, but only if n is not 1.

func pluralizeFirst ( s string , n int ) string {

if n == 1 {

return s

}

w := strings . Fields ( s )

w [ 0 ] += "s"

return strings . Join ( w , " " )

}



// p is string to slur, d is drunkenness, from 0 to 99

func slur ( p string , d int ) string {

// shuffle only interior letters

a := [] byte ( p [ 1 : len ( p ) - 1 ])

// adapted from Knuth shuffle task.

// shuffle letters with probability d/100.

for i := len ( a ) - 1 ; i > = 1 ; i -- {

if rand . Intn ( 100 ) > = d {

j := rand . Intn ( i + 1 )

a [ i ], a [ j ] = a [ j ], a [ i ]

}

}

// condense spaces

w := strings . Fields ( p [: 1 ] + string ( a ) + p [ len ( p ) - 1 :])

return strings . Join ( w , " " )

}

Output:

Things start out pretty well...

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

Soon,

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

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

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

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

--

-- 99 Bottles of Beer in Go!

-- John Knottenbelt

--

-- Go! is a multi-paradigm programming language that is oriented

-- to the needs of programming secure, production quality, agent

-- based applications.

--

-- http://www.doc.ic.ac.uk/~klc/dalt03.html

--



main .. {

include "sys:go/io.gof".

include "sys:go/stdlib.gof".



main() ->

drink(99);

stdout.outLine("Time to buy some more beer...").



drink(0) -> {}.

drink(i) -> stdout.outLine(

bottles(i) <> " on the wall,

" <>

bottles(i) <> ".

" <>

"take one down, pass it around,

" <>

bottles(i-1) <> " on the wall.

");

drink(i-1).



bottles(0) => "no bottles of beer".

bottles(1) => "1 bottle of beer".

bottles(i) => i^0 <> " bottles of beer".

}

[296,{3/)}%-1%["No more"]+[" bottles":b]294*[b-1<]2*+[b]+[" of beer on the wall

".8<"

Take one down, pass it around

"+1$n+]99*]zip

module Bottles



augment java.lang.Integer {

function bottles = |self| -> match {

when self == 0 then "No bottles"

when self == 1 then "One bottle"

otherwise self + " bottles"

}

}



function main = |args| {

99: downTo(1, |i| {

println(i: bottles() + " of beer on the wall,")

println(i: bottles() + " of beer!")

println("Take one down, pass it around,")

println((i - 1): bottles() + " of beer on the wall!")

println("--------------------------------------")

})

}



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



}



Basic Solution [ edit ]

With a closure to handle special cardinalities of bottles.

def bottles = { "${it==0 ? 'No more' : it} bottle${it==1 ? '' : 's' }" }



99 . downto ( 1 ) { i ->

print """

${bottles(i)} of beer on the wall

${bottles(i)} of beer

Take one down, pass it around

${bottles(i-1)} of beer on the wall

"""

}

Single Print Version [ edit ]

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

298 . downto ( 2 ) {

def ( m,d ) = [ it % 3, ( int ) it/ 3 ]

print "${m==1?'

':''}${d?:'No more'} bottle${d!=1?'s':''} of beer" +

"${m?' on the wall':'

Take one down, pass it around'}

"

}

Bottomless Beer Solution [ edit ]

Using more closures to create a richer lyrical experience.

def bottles = { "${it==0 ? 'No more' : it} bottle${it==1 ? '' : 's' }" }



def initialState = {

"""${result(it)}

${resultShort(it)}"""

}



def act = {

it > 0 ?

"Take ${it==1 ? 'it' : 'one'} down, pass it around" :

"Go to the store, buy some more"

}



def delta = { it > 0 ? - 1 : 99 }



def resultShort = { "${bottles(it)} of beer" }



def result = { "${resultShort(it)} on the wall" }



// //// uncomment commented lines to create endless drunken binge //// //

// while (true) {

99 . downto ( 0 ) { i ->

print """

${initialState(i)}

${act(i)}

${result(i+delta(i))}

"""

}

// Thread.sleep(1000)

// }

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

Start,Programs,Accessories,Calculator,Button:9,Button:9,

Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals],

Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals],

Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals],

Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals]



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

Just a basic loop counting down to one. No big deal. Note that at BOTTLES=1, it is not grammatically correct.

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



$plural = "s";

$x = 99;

while ($x > 0) {

echo "$x bottle$plural of beer on the wall";

echo "$x bottle$plural of beer";

echo "Take one down, pass it around";

$x -= 1;

if ($x == 1)

$plural = "";

if ($x > 0)

echo "$x bottle$plural of beer on the wall

";

else

echo "No more bottles of beer on the wall!";

}

Brevity [ edit ]

A relatively concise solution:

main = mapM_ ( putStrLn . beer ) [ 99 , 98 .. 0 ]

beer 1 = "1 bottle of beer on the wall

1 bottle of beer

Take 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

"

++ show v

++ " bottles of beer

Take one down, pass it around

"

++ head ( lines $ beer $ v - 1 ) ++ "

"

List comprehension [ edit ]

As a list comprehension:

import qualified Char



main = putStr $ concat

[ up ( bob n ) ++ wall ++ ", " ++ bob n ++ ".

" ++

pass n ++ bob ( n - 1 ) ++ wall ++ ".



" |

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"

Writer monad and Template Haskell [ edit ]

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

{-# LANGUAGE TemplateHaskell #-}

-- build with "ghc --make beer.hs"

module Main where

import Language . Haskell . TH

import Control . Monad . Writer



-- This is calculated at compile time, and is equivalent to

-- songString = "99 bottles of beer on the wall

99 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

"

sing $ n `bottlesOfBeer` "

"

sing $ "Take one down, pass it around

"

sing $ ( n - 1 ) `bottlesOfBeer` "on the wall



"



song = execWriter $ mapM_ verse [ 99 , 98 .. 1 ]



in return $ LitE $ StringL $ song )



main = putStr songString

Avoiding append by spelling bottle backwards [ edit ]

Is there something just a little prickly and displeasing about (++) ? Monoid (<>) is less spiky, but neither is needed when 'bottle' is written backwards.

location , distribution , solution :: String

[ location , distribution , solution ] =

[ "on the wall"

, "Take one down, pass it around"

, "Better go to the store to buy some more"

]



asset :: Int -> String

asset n =

let suffix n

| 1 == n = [ ]

| otherwise = [ 's' ]

in unwords [ show n , ( reverse . concat ) $ suffix n : [ "elttob" ] ]



incantation :: Int -> String

incantation n =

let inventory = unwords . ( : [ location ] ) . asset

in case n of

0 -> solution

_ -> unlines [ inventory n , asset n , distribution , inventory $ pred n ]



main :: IO ( )

main = putStrLn $ unlines ( incantation <$> [ 99 , 98 .. 0 ] )

Simple solution [ edit ]

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!

");

}

else

{

Sys.println("No more bottles of beer on the wall!");

}

bottles--;

}

}

}

Macro solution [ edit ]

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

class Bottles {



static public function main () : Void {

singBottlesOfB