99 bottles of beer

From Rosetta Code
Revision as of 03:02, 26 December 2013 by Dbabbitt (talk | contribs) (→‎Classic tag based: Added CFML)
Task
99 bottles of beer
You are encouraged to solve this task according to the task description, using any language you may know.

In this puzzle, write code to print out the entire "99 bottles of beer on the wall" song. For those who do not know the song, the lyrics follow this form:

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

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

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

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


0815

ATTENTION: Since 0815 output is in Hexadecimals only, the bottles count is obviously in Hexadecimals too. So if you see something like: "1E Bottles of beer..." don’t panic, everything is OK.

<lang 0815> <:63:x<:20:=<:62:>=>=><:6F:x<:74:=<:6C:>=>>=><:65:x<:73:=<:20:>=>=><:6F:x<:66:=<:20:>=>=> <:62:x<:65:=<:72:>=>>=><:20:x<:6F:=<:6E:>=>=><:20:x<:74:=<:68:>=>=><:65:x<:20:=<:77:>=>=> <:61:x<:6C:=>=>><:54:x<:61:=<:6B:>=>=><:65:x<:20:=<:6F:>=>=><:6E:x<:65:=<:20:>=>=><:64:x <:6F:=<:77:>=>=><:6E:x<:20:=<:61:>=>=><:6E:x<:64:=<:20:>=>=><:70:x<:61:=<:73:>=>=>><:20:x <:69:=<:74:>=>=><:20:x<:61:=<:72:>=>=><:6F:x<:75:=<:6E:>=>=><:64:~>}:_start:{~%><:1c:~ }:_99:~{~$>=<:01:x-^:_99:<:0D:~$@:20:{~%><:10:~}:_98:~{~$>=<:01:x-^:_98:<:0D:~$@:c:<:20:~ }:_97:~{~$>=<:01:x-^:_97:<:0D:~${x<:01:x->&==<:01:-#:_322:{~%><:1c:~}:_96:~{~$>=<:01:x- ^:_96:<:d:~$$@:20:{~>&^:_start:}:_90:?<:4E:x<:6F:=<:20:>=>=><:6D:x<:6F:=<:72:>=>=><:65:x <:20:=<:62:>=>=><:6F:x<:74:=<:6C:>=>>=><:65:x<:73:=<:20:>=>=><:6F:x<:66:=<:20:>=>=><:62:x <:65:=<:72:>=>>=><:20:x<:6F:=<:6E:>=>=><:20:x<:74:=<:68:>=>=><:65:x<:20:=<:77:>=>=><:61:x <:6C:=>=>><:02:~}:_70:><:23:~}:_80:~{~$>=<:01:x-^:_80:{~<:01:=-#:_60:<:0D:~$$=^:_70:}:_60: <:0D:~$<:17:~}:_81:~{~$=<:01:x-^:_81:<:0D:~$?<:47:x<:6F:=<:20:>=>=><:74:x<:6F:=<:20:>=>=> <:74:x<:68:=<:65:>=>=><:20:x<:73:=<:74:>=>=><:6F:x<:72:=<:65:>=>=><:20:x<:61:=<:6E:>=>=> <:64:x<:20:=<:62:>=>=><:75:x<:79:=<:20:>=>=><:73:x<:6F:=<:6D:>=>=><:65:x<:20:=<:6D:>=>=> <:6F:x<:72:=<:65:>=>=><:21:~}:_18:~{~$=<:01:x-^:_18:<:0D:~$<:63:x<:20:=<:62:>=>=><:6F:x <:74:=<:6C:>=>>=><:65:x<:73:=<:20:>=>=><:6F:x<:66:=<:20:>=>=><:62:x<:65:=<:72:>=>>=><:20: x<:6F:=<:6E:>=>=><:20:x<:74:=<:68:>=>=><:65:x<:20:=<:77:>=>=><:61:x<:6C:=>=>>{~%<:1c:~ }:_21:~{~$=<:01:x-^:_21:<:0D:~$^:end:}:_322:?<:01:x<:20:=<:62:>=>=><:6F:x<:74:=<:6C:>=>>= ><:65:x<:20:=<:6F:>=>=><:66:x<:20:=>=><:62:x<:65:=<:72:>=>>=><:20:x<:6F:=<:6E:>=>=><:20:x <:74:=<:68:>=>=><:65:x<:20:=<:77:>=>=><:61:x<:6C:=>=>><:54:x<:61:=<:6B:>=>=><:65:x<:20:= <:6F:>=>=><:6E:x<:65:=<:20:>=>=><:64:x<:6F:=<:77:>=>=><:6E:x<:20:=<:61:>=>=><:6E:x<:64:= <:20:>=>=><:70:x<:61:=<:73:>=>=>><:20:x<:69:=<:74:>=>=><:20:x<:61:=<:72:>=>=><:6F:x<:75:= <:6E:>=>=><:64:~>{~%><:1b:~}:_299:~{~$>=<:01:x-^:_299:<:0D:~$$@:20:{~%><:1b:~}:_298:~{~$> =<:01:x-^:_298:<:0D:~$@:20:{~%<:f:~}:_297:~{~$>=<:01:x-^:_297:<:0D:~$@:c:<:20:~}:_296:~{~ $>=<:01:x-^:_296:<:0D:~${x<:01:x->&==<:01:-^:_90: </lang>

6502 Assembly

IMPORTANT NOTE: This assembly language solution is targeted at the Apple 1. The Apple 1 was an innovative device for its time, but it's quite primitive by modern standards, and it had NO support for lower-case letters. Therefore, the UPPER-CASE output of this example accurately represents the only reasonable one for this device, and cannot be "fixed" due to non-compliance, only deleted.

<lang 6502 Assembly> .CR 6502

  .TF AP1BEER.O,AP1
  .LF AP1BEER.LST
  .OR $0BEE
-------------------------------------;
BEER SONG IN 6502 ASSEMBLY LANGUAGE ;
BY BARRYM 2010-05-30  ;
THANKS TO SBPROJECTS.COM FOR LOTS  ;
OF VALUABLE INFORMATION AND A  ;
VERY NICE ASSEMBLER!  ;
-------------------------------------;
THE TARGET MACHINE FOR THIS PROGRAM ;
IS THE APPLE 1, BUT IT WOULD BE  ;
EASY TO MAKE IT RUN ON OTHER 65XX ;
MACHINES BY CHANGING THE NEXT TWO ;
EQUATES. SOME MACHINE-TESTED  ;
EXAMPLES
;
APPLE II, +, E, C
$FDED, $80  ;
COMMODORE 64
$FFD2, $00  ;
-------------------------------------;

ECHO = $FFEF ;EMIT A REG AS ASCII ORMASK = $80  ;($00 FOR + ASCII)

MAXBEER = 99 ;INITIAL BEER COUNT

-------------------------------------;
X REG. IS THE BOTTLE COUNTER.  ;
Y REG. IS THE STRING INDEX POINTER, ;
AND THE TENS DIGIT IN THE BINARY- ;
TO-ASCII CONVERSION ROUTINE.  ;
A REG. HANDLES EVERYTHING ELSE WITH ;
A LITTLE HELP FROM THE STACK.  ;
ZERO PAGE ISN'T DIRECTLY DISTURBED. ;
-------------------------------------;
EMIT COMPLETE CORRECT SONG ADJUSTED ;
FOR UPPER-CASE 40-COLUMN DISPLAY. ;
-------------------------------------;
  LDX #MAXBEER    ;X=MAXBEER
  BNE PRSONG      ;SING THE SONG & RTS
-------------------------------------;
EMIT WHOLE SONG UP TO LAST SENTENCE.;
-------------------------------------;

BEERME:

  LDY #TAKE1-TXT  ;? "TAKE ... AROUND,"
  JSR PRBOB       ;? X;" BOT ... WALL."

PRSONG: ;  ;?

  LDY #CR-TXT     ;? X;" BOT ... WALL," 
  JSR PRBOB       ;? X;" BOT ... BEER."
  DEX             ;X=X-1
  BPL BEERME      ;IF X>=0 THEN BEERME
-------------------------------------;
EMIT LAST SENTENCE AND FALL THROUGH.;
-------------------------------------;
  LDX #MAXBEER    X=MAXBEER:
? "GO TO ... MORE,"
-------------------------------------;
PRINT A PROPERLY PUNCTUATED "BOTTLE ;
OF BEER" SENTENCE.  ;
-------------------------------------;

PRBOB:

  TYA
  PHA             ;SAVE THE PRE$ PTR
  JSR PUTS        ;? PRE$;
  TXA             ;IF X=0 THEN
  BEQ PRBOTT      ;   ? "NO MORE";
  LDY #"0"-1      ;ELSE
  SEC             ;(

DIV10:

  SBC #10         ;   Y=INT(X/10)
  INY
  BCS DIV10
  ADC #10+'0'
  CPY #"0"
  BEQ ONEDIG
  PHA             ;   IF Y>0 THEN
  TYA                   ? Y;
  JSR PUTCH
  PLA             ;   ? X MOD 10;

ONEDIG:

  LDY #BOTTL-TXT  ;)

PRBOTT:

  JSR PUTCH       ;? " BOTTLE";
  CPX #1
  BNE PLURAL
  INY             ;IF X<>1 THEN ? "S";

PLURAL:

  JSR PUTS        ;? " OF BEER";
  PLA             ;RECALL THE PRE$ PTR
  CMP #COMCR-TXT
  BEQ PRDOT
  PHA             ;IF APPROPRIATE THEN
  JSR PUTS        ;   ? " ON THE WALL";
  PLA
  LDY #COMCR-TXT  ;IF APPROPRIATE THEN
  CMP #CR-TXT     ;   ? ",":
  BEQ PRBOB       ;   ? X;" ... BEER";

PRDOT:

  LDY #DOTCR-TXT  ;? "."
-------------------------------------;
EMIT A HI-BIT-SET TERMINATED STRING ;
@ OFFSET Y AND EXIT WITH Y @ THE  ;
BEGINNING OF THE NEXT STRING.  ;
-------------------------------------;

PUTS:

  LDA TXT,Y       ;GRAB A STRING CHAR
  INY             ;ADVANCE STRING PTR

PUTCH:

  PHA
  ORA #ORMASK
  AND #ORMASK+127 ;FORMAT CHAR FOR ECHO
  JSR ECHO        ;SHOOT IT TO CONSOLE
  PLA
  BPL PUTS        ;LOOP IF APPROPRIATE
  RTS
-------------------------------------;
OPTIMIZED SONG LYRIC STRINGS.  ;
-------------------------------------;

TXT: TAKE1:

  .AS "TAKE ONE DOWN AND"
  .AS " PASS IT AROUND"

COMCR:

  .AS ","

CR:

  .AT #13
  .AS "NO MORE"

BOTTL:

  .AT " BOTTLE"
  .AT "S OF BEER"
  .AT " ON THE WALL"

DOTCR:

  .AT ".",#13
  .AS "GO TO THE STORE AND"
  .AT " BUY SOME MORE,",#13
  .EN
-------------------------------------;
APPLE 1 MONITOR HEX DUMP FOLLOWS.  ;
ENTER AS SHOWN INTO THE MONITOR,  ;
AND LET THE BEER FLOW!!  ;
-------------------------------------;

0BEE

A2 63 D0 05 A0 00 20 01 0C A0 21 20 01
0C CA 10 F3 A2 63 98 48 20 3C 0C 8A F0
16 A0 AF 38 E9 0A C8 B0 FB 69 3A C0 B0
F0 06 48 98 20 40 0C 68 A0 29 20 40 0C
E0 01 D0 01 C8 20 3C 0C 68 C9 20 F0 0B
48 20 3C 0C 68 A0 20 C9 21 F0 C7 A0 45
B9 4C 0C C8 48 09 80 29 FF 20 EF FF 68
10 F1 60 54 41 4B 45 20 4F 4E 45 20 44
4F 57 4E 20 41 4E 44 20 50 41 53 53 20
49 54 20 41 52 4F 55 4E 44 2C 8D 4E 4F
20 4D 4F 52 45 20 42 4F 54 54 4C C5 53
20 4F 46 20 42 45 45 D2 20 4F 4E 20 54
48 45 20 57 41 4C CC 2E 8D 47 4F 20 54
4F 20 54 48 45 20 53 54 4F 52 45 20 41
4E 44 20 42 55 59 20 53 4F 4D 45 20 4D
4F 52 45 2C 8D

BEER</lang>

6800 Assembly

<lang 6800 Assembly> .cr 6800

       .tf  beer6800.obj,AP1
       .lf  beer6800
=====================================================;
Beer Song for the Motorola 6800 microprocessor  ;
by barrym 2011-04-19  ;
-----------------------------------------------------;
Prints the correct, complete song lyrics to a full  ;
ascii terminal (console) connected to a 1970s  ;
vintage SWTPC 6800 system, which is the target  ;
device for this assembly.  ;
Many thanks to
;
swtpc.com for hosting Michael Holley's documents! ;
sbprojects.com for a very nice assembler!  ;
swtpcemu.com for a very capable emulator!  ;
The 6800 microprocessor is the slightly older, less ;
popular, and more expensive step-brother of the  ;
6502. Numerous similarities exist between the  ;
assembly languages of the two, but the 6800 has  ;
its own distinct flavor, which is (judging by how ;
compact the code ended up) well suited to this  ;
type of small program. I am especially impressed ;
with the two-byte 'bsr' instruction, and I make  ;
extensive use of it here.  ;
Effort was made to keep the code footprint as small ;
as possible by re-using substrings and code in a  ;
hacker-like style that makes the program flow a  ;
bit strange to the human eye (the 6800 gobbles it ;
up without complaint). The final tally
97 bytes ;
of instructions, 108 bytes of text, and about 11  ;
bytes of stack. This includes integer-to-ascii  ;
conversion, blank line between verses, removal of ;
"s" from "1 bottles", substitution of "no more"  ;
for "0", and proper capitalization of "No more".  ;
reg b is the beer counter  ;
reg x is the string pointer  ;
reg a handles everything else (with a little help  ;
from the system stack)  ;
-----------------------------------------------------;

outeee = $e1d1 ;ROM: console putchar routine stbeer = 99 ;Must be in the range [0..99]

       .or  $0f00
=====================================================;
Initialize, sing the song, and exit  ;
-----------------------------------------------------;

main ldab #stbeer ;Beer count = stbeer

       bsr  prsong     ;Sing the entire song
       swi             ;Return to the monitor.
=====================================================;
Emit the entire song up to the last sentence  ;
-----------------------------------------------------;

beerme bsr prbob2 ;Emit second sentence of verse prsong ldx #nline ;Blank line between verses

       ldaa #'N'       ;First sentence type = 'N'
       bsr  prbob      ;Emit 1st sentence of verse
       decb            ;Beer count -= 1
       bpl  beerme     ;If beer count >= 0 then beerme
=====================================================;
Set up the last sentence and fall through to prbob2 ;
-----------------------------------------------------;
       ldab #stbeer    ;Beer count = stbeer
       ldx  #store     ;x$ = "Go to the store ..."
=====================================================;
Emit a properly punctuated bottle-of-beer sentence, ;
using beer counter in reg b, pre-string pointer  ;
in reg x, and the sentence type in reg a ('N' =  ;
sentence 1, 'o' = sentence 1.5, 'n' = sentence 2) ;
-----------------------------------------------------;

prbob2 ldaa #'n' ;Second sentence type = 'n' prbob psha ;Stack sentence type for later

       bsr  puts       ;Emit pre-string
       pula            ;Check sentence type and use
       psha            ;  it to prepare the upper- or
       anda #'n'       ;  lower-case of "no more"
       ldx  #omore     ;x$ = "o more bottle"
       tstb            ;If beer count = 0 then
       beq  prbott     ;  skip over the i-to-a
       ldx  #bottl     ;x$ = " bottle"
=====================================================;
I-to-A (inline)
convert int in b to ascii and emit ;
with leading zero suppression (0 <= # <= 99)!  ;
-----------------------------------------------------;
       pshb            ;Stack beer count
       ldaa #-1        ;  (divten trashes it)

divten subb #10 ;b = ones digit - 10

       inca            ;a = tens digit
       bcc  divten     ;If a = 0 then
       beq  onedig     ;  suppress leading zero
       adda #"0"       ;else translate tens digit to
       bsr  putch      ;  shifted ascii and emit

onedig addb #'0'+10 ;Translate ones digit to ascii

       tba             ;  and leave it in a for putch
       pulb            ;Restore beer count
-----------------------------------------------------;

prbott bsr putch ;Emit a;x$;

       cmpb #1         ;If beer count = 1
       bne  plural     ;then
       inx             ;  skip over the "s"

plural bsr puts ;Emit " ... beer";

       pula            ;Restore sentence type
       cmpa #'o'       ;If type <> 'o'
       beq  putdot     ;then
       psha            ;  emit " on the wall";
       bsr  puts       ;  if type = 'N' then loop
       pula            ;    back to finish the
       adda #33        ;    first sentence with
       bpl  prbob      ;    type = 'o', x$ = ", "

putdot ldx #dotnl ;x$ = ".\n"

=====================================================;
Emit string @ x and leave x @ start of next string  ;
-----------------------------------------------------;

puts ldaa 0,x ;a = raw character removed

       inx             ;  from the beginning of x$
=====================================================;
Emit a as ascii and loop into x$ if hi-bit is clear ;
-----------------------------------------------------;

putch psha ;Stack raw char

       anda #$7f       ;Mask off the hi-bit
       jsr  outeee     ;Emit a as 7-bit ascii
       pula            ;Restore raw char
       tsta            ;If hi-bit is clear then
       bpl  puts       ;  loop back into x$
       rts             ;All 8 'bsr's use this 'rts'!
=====================================================;
Optimized song lyric strings, carefully arranged to ;
allow the prbob subroutine to take full advantage ;
of the x register side-effects of puts  ;
-----------------------------------------------------;

omore .as "o more" bottl .at " bottle"

       .at  "s of beer"
       .at  " on the wall"
       .at  ", "

dotnl .as "." nline .at #13,#10

       .at  "Take one down and pass it around, "

store .at "Go to the store and buy some more, "

       .en
=====================================================;
The following is a hex dump of the object file,  ;
suitable for copying and pasting into the 6800  ;
emulator available at swtpcemu.com!  ;
-----------------------------------------------------;

e0F00 C6 63 8D 03 3F 8D 0F CE 0F 86 86 4E 8D 0A 5A 2A e0F10 F4 C6 63 CE 0F AA 86 6E 36 8D 38 32 36 84 6E CE e0F20 0F 61 5D 27 15 CE 0F 67 37 86 FF C0 0A 4C 24 FB e0F30 27 04 8B B0 8D 20 17 8B 3A 33 8D 1A C1 01 26 01 e0F40 08 8D 10 32 81 6F 27 08 36 8D 08 32 8B 21 2A C8 e0F50 CE 0F 85 A6 00 08 36 84 7F BD E1 D1 32 4D 2A F3 e0F60 39 6F 20 6D 6F 72 65 20 62 6F 74 74 6C E5 73 20 e0F70 6F 66 20 62 65 65 F2 20 6F 6E 20 74 68 65 20 77 e0F80 61 6C EC 2C A0 2E 0D 8A 54 61 6B 65 20 6F 6E 65 e0F90 20 64 6F 77 6E 20 61 6E 64 20 70 61 73 73 20 69 e0FA0 74 20 61 72 6F 75 6E 64 2C A0 47 6F 20 74 6F 20 e0FB0 74 68 65 20 73 74 6F 72 65 20 61 6E 64 20 62 75 e0FC0 79 20 73 6F 6D 65 20 6D 6F 72 65 2C A0 j0F00</lang>

ABAP

<lang ABAP>REPORT z99bottles.

DATA lv_no_bottles(2) TYPE n VALUE 99.

DO lv_no_bottles TIMES.

 WRITE lv_no_bottles NO-ZERO.
 WRITE ' bottles of beer on the wall'.
 NEW-LINE.
 WRITE lv_no_bottles NO-ZERO.
 WRITE ' bottles of beer'.
 NEW-LINE.
 WRITE 'Take one down, pass it around'.
 NEW-LINE.
 SUBTRACT 1 FROM lv_no_bottles.
 WRITE lv_no_bottles NO-ZERO.
 WRITE ' bottles of beer on the wall'.
 WRITE /.

ENDDO.</lang>

ACL2

<lang Lisp>(defun bottles-of-beer (n)

  (if (zp n)
      nil
      (prog2$ (cw (concatenate 'string
                  "~%"
                  "~N0 bottle~#1~[~/s~] of beer on the wall,~%"
                  "~n0 bottle~#1~[~/s~] of beer.~%"
                  "Take one down, pass it around,~%"
                  "~n2 bottle~#3~[~/s~] of beer on the wall.~%")
                  n
                  (if (= n 1) 0 1)
                  (1- n)
                  (if (= n 2) 0 1))
              (bottles-of-beer (- n 1)))))</lang>

ActionScript

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

Ada

Simple version

<lang ada>with Ada.Text_Io; use Ada.Text_Io;

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

Concurrent version

with 1 task to print out the information and 99 tasks to specify the number of bottles <lang Ada>with Ada.Text_Io; use Ada.Text_Io;

procedure Tasking_99_Bottles is

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

begin

  for I in Task_List'range loop -- Create 99 Counter tasks
     Task_List(I) := new Counter(I);
  end loop;

end Tasking_99_Bottles;</lang>

Aime

<lang aime>integer main(void) {

   cardinal bottles;
   bottles = 99;
   do {

o_cardinal(bottles);

       o_text(" bottles of beer on the wall\n");

o_cardinal(bottles);

       o_text(" bottles of beer\n");
       o_text("Take one down, pass it around\n");
       bottles -= 1;

o_cardinal(bottles);

       o_text(" bottles of beer on the wall\n\n");
   } while (bottles);
   return 0;

}</lang>

ALGOL 68

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

<lang algol68>main:(

  FOR bottles FROM 99 TO 1 BY -1 DO
    printf(($z-d" bottles of beer on the wall"l$, bottles));
    printf(($z-d" bottles of beer"l$, bottles));
    printf(($"Take one down, pass it around"l$));
    printf(($z-d" bottles of beer on the wall"ll$, bottles-1))
  OD

)</lang>

AmigaE

<lang amigae>PROC main()

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

ENDPROC</lang>

Ant

Implementation in Apache Ant, due to the limitations of Ant, this requires ant-contrib for arithmetic operations and a dummy target to keep Ant from detecting the loop. <lang xml><?xml version="1.0"?> <project name="n bottles" default="99_bottles">

 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
 <property name="count" value="99"/>
 <target name="99_bottles">
   <antcall target="bottle">
     	<param name="number" value="${count}"/>
   </antcall>
 </target>
 <target name="bottle">
   <echo message="${number} bottles of beer on the wall"/>
   <echo message="${number} bottles of beer"/>
   <echo message="Take one down, pass it around"/>
   
   <echo message="${result} bottles of beer on the wall"/>
   <if>
     <not><equals arg1="${result}" arg2="0" /></not>
     <then>
       <antcall target="bottleiterate">
         <param name="number" value="${result}"/>
       </antcall>
     </then>
   </if>
 </target>
 <target name="bottleiterate">
   <antcall target="bottle">
     	<param name="number" value="${number}"/>
   </antcall>
 </target>

</project></lang>

APL

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

Applescript

<lang Applescript>repeat with beerCount from 99 to 1 by -1

 set bottles to "bottles"
 if beerCount < 99 then
   if beerCount = 1 then
     set bottles to "bottle"
   end
   log "" & beerCount & " " & bottles & " of beer on the wall"
   log ""
 end
 log "" & beerCount & " " & bottles & " of beer on the wall"
 log "" & beerCount & " " & bottles & " of beer"
 log "Take one down, pass it around"

end log "No more bottles of beer on the wall!"</lang>

Arbre

<lang Arbre> bottle(x):

 template: '
 $x bottles of beer on the wall.
 $x bottles of beer.
 Take one down and pass it around,
 $y bottles of beer on the wall.
 '
 if x==0
   template~{x: 'No more', y: 'No more'}
 else
   if x==1
     template~{x: x, y: 'No more'}
   else
     template~{x: x, y: x-1}

bottles(n):

 for x in [n..0]
   bottle(x)

99bottles():

 bottles(99) -> io

</lang>


Argile

<lang Argile>use std

let X be an int for each X from 99 down to 1

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

ATS

<lang ATS>/* .<n>. is a termination metric to prove that the function terminates. It can be omitted. */ fun bottles {n:nat} .<n>. (n: int n): void =

   if n = 0 then
       ()
   else begin
       printf ("%d bottles of beer on the wall\n", @(n));
       printf ("%d bottles of beer\n", @(n));
       printf ("Take one down, pass it around\n", @());
       printf ("%d bottles of beer on the wall\n", @(n-1));
       bottles (n - 1)
   end

implement main () = bottles (99)</lang>

AutoHotkey

<lang AutoHotkey>; RC: 99 bottles of beer

  b = 99
  Loop, %b% {
     s .= b . " bottles of beer on the wall,`n"
       . b . " bottles of beer.`nTake one down, pass it around,`n"
       . b-1 . " bottles of beer on the wall.`n`n"
     b--
  }
  Gui, Add, Edit, w200 h200, %s%
  Gui, Show, , 99 bottles of beer

Return ; end of auto-execute section

GuiClose:

  ExitApp

Return</lang>

Delayed Sing along <lang AutoHotkey>n=99 Gui, Font, s20 cMaroon, Comic Sans MS Gui, Add, Text, w500 vLyrics, %n% bottles of beer on the wall... Gui, Show Loop {

Sleep, 2000
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer.":n " bottle of beer."
Sleep, 2000
GuiControl,,Lyrics,% n ? "Take one down, pass it around...":"Go to the store, buy some more..."
Sleep, 2000
n := n ? --n:99
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall.":n " bottle of beer on the wall."
Sleep, 2000
GuiControl,,Lyrics,% n!=1 ? n " bottles of beer on the wall...":n " bottle of beer on the wall..."

} GuiClose: ExitApp</lang>

Fast and Short <lang AutoHotkey>b=99 Loop, %b% { s := b " bottles of beer on the wall, " b " bottles of beer, Take one down, pass it around " b-1 " bottles of beer on the wall" b-- TrayTip,,%s% sleep, 40 }</lang>

With a GUI and slight grammatical variation: <lang AutoHotkey>N=o more Z=99 L:=Z M:=(B:=" bottle")"s" Loop 99 V.=L (W:=(O:=" of beer")" on the wall")",`n"L O ",`nTake one down and pass it around,`n"(L:=(--Z ? Z:"N"N)(Z=1 ? B:M))W ".`n`n" Gui,Add,Edit,w600 h250,% V L W ", n"N M O ".`nGo to the store and buy some more, 99"M W "." Gui,Show Return GuiClose: ExitApp</lang>

AutoIt

<lang AutoIt>


local $bottleNo=99 local $lyrics=" "

While $bottleNo<>0 If $bottleNo=1 Then $lyrics&=$bottleNo & " bottles of beer on the wall" & @CRLF $lyrics&=$bottleNo & " bottles of beer" & @CRLF $lyrics&="Take one down, pass it around" & @CRLF Else $lyrics&=$bottleNo & " bottles of beer on the wall" & @CRLF $lyrics&=$bottleNo & " bottles of beer" & @CRLF $lyrics&="Take one down, pass it around" & @CRLF EndIf If $bottleNo=1 Then $lyrics&=$bottleNo-1 & " bottle of beer" & @CRLF Else $lyrics&=$bottleNo-1 & " bottles of beer" & @CRLF EndIf $bottleNo-=1 WEnd MsgBox(1,"99",$lyrics) </lang>

Easier to read output to Console

<lang AutoIt> $bottles = 99 $lyrics1 = " bottles of beer on the wall. " $lyrics2 = " bottles of beer. Take one down and pass it around. "

For $i = $bottles To 1 Step -1 If $i = 1 Then $lyrics1 = " bottle of beer on the wall. " $lyrics2 = " bottle of beer. Take one down and pass it around. " $lyrics3 = " Go to the store and get some more! No bottles of beer on the wall!" ConsoleWrite($bottles & $lyrics1 & $bottles & $lyrics2 & $lyrics3 & @CRLF) Else ConsoleWrite($bottles & $lyrics1 & $bottles & $lyrics2 & $bottles - 1 & $lyrics1 & @CRLF) $bottles -= 1 EndIf Next </lang>

AWK

<lang awk>{ i = 99 while (i > 0) {print i, " bottles of beer on the wall," print i, " bottles of beer." print "Take one down, pass it around," i-- print i, " bottles of beer on the wall\n"}}</lang>

Babel

<lang babel>main: { 99 bottles }

bottles!:

   { x set
       { bw
       bx cr <<
       "Take one down, pass it around\n" << 
       1 x -= 
       bw "\n" << }
   x times }

b  : " bottles of beer" bx!: { x %d << b } w  : " on the wall" bw!: { bx w . cr << }

x: [0]</lang>

BASIC

Works with: QuickBASIC version 4.5

Sound

This version plays the tune 100 times while printing out the lyrics (not synchronized). <lang qbasic>PLAY "<" FOR x = 99 TO 0 STEP -1

 PRINT x; "bottles of beer on the wall"
 PRINT x; "bottles of beer"
 PRINT "Take one down, pass it around"
 PRINT x-1; "bottles of beer on the wall"
 PRINT
 PLAY "e-8e-8e-8<b-8b-8b-8>e-8e-8e-8e-4"'X bottles of beer on the wall
 PLAY "f8f8f8c8c8c8f4"'X bottles of beer
 PLAY "d4d8d8 N0 d8d8d8d4"'take one down, pass it around
 PLAY "<a+8a+8a+8>c8c8d8d+8d+8d+8d+4"'X-1 bottles of beer on the wall

NEXT x</lang>

Text

<lang qbasic>FOR x = 99 TO 1 STEP -1

 PRINT x; "bottles of beer on the wall"
 PRINT x; "bottles of beer"
 PRINT "Take one down, pass it around"
 PRINT x-1; "bottles of beer on the wall"
 PRINT

NEXT x</lang>

Applesoft BASIC

<lang Applesoft BASIC> 10 HOME 20 FOR B=99 TO 1 STEP -1 30 PRINT B;" BOTTLE OF BEER ON THE WALL" 40 PRINT B;" BOTTLE OF BEER ON THE WALL" 50 PRINT "TAKE ONE DOWN, PASS IT AROUND" 60 PRINT B-1;" BOTTLE OF BEER ON THE WALL" 70 NEXT B </lang>

BASIC256

<lang BASIC256>#length of querter and eight note in ms n4 = 1000 * 60 / 80 / 4 n8 = n4 / 2

  1. frequency of musical notes in hz

e = 330 ef = 311 b = 247 bf = 233 f = 349 c = 262 d = 294 ds = 311 a = 220

dim notes(1) dim lengs(1)

  1. redim is automatic when using a {} list to assign an array

notes = {ef, ef, ef, bf, bf, bf, ef, ef, ef, ef, f , f , f , c , c , c , f , d , d , d , d , d , d , d , bf, bf, bf, c , c , ef, ef, ef, ef, ef} lengs = {n8, n8, n8, n8, n8, n8, n8, n8, n8, n4, n8, n8, n8, n8, n8, n8, n4, n4, n8, n8, n8, n8, n8, n4, n8, n8, n8, n8, n8, n8, n8, n8, n8, n4 }

for x = 99 to 1 step -1

  for t = 0 to notes[?]-1
     if t = 0 then print x + " bottles of beer on the wall"
     if t = 11 then print x + " bottles of beer"
     if t = 18 then print "Take one down, pass it around"
     if t = 25 then print(x-1) + " bottles of beer on the wall"
     sound notes[t], lengs[t]
     pause .002
  next t
  print

next x </lang>

BBC BASIC

<lang bbcbasic>

     N_Bottles = 99
     
     beer$ = " of beer"
     wall$ = " on the wall"
     unit$ = "99 bottles"
     
     WHILE N_Bottles >= 0
       
       IF N_Bottles=0 THEN
         PRINT '"No more bottles" beer$ wall$ ", " unit$ beer$ "."
         PRINT "Go to the store and buy some more, ";
       ELSE
         PRINT 'unit$ beer$ wall$ ", " unit$ beer$ "."
         PRINT "Take one down and pass it around, ";
       ENDIF
       
       N_Bottles -= 1
       
       CASE N_Bottles OF
         WHEN 0:
           unit$ = "no more bottles"
         WHEN 1:
           unit$ = "1 bottle"
         OTHERWISE:
           unit$ = STR$((N_Bottles + 100) MOD 100) + " bottles"
       ENDCASE
       
       PRINT unit$ beer$ wall$ "."
       
     ENDWHILE
     
     END

</lang>

Creative Basic

window version

<lang Creative Basic>DEF Win:WINDOW DEF Close:CHAR DEF ScreenSizeX,ScreenSizeY:INT

DECLARE VSpace(Number:UINT) DECLARE CLR()

DEF TheLine$[4],Number$,Erase:STRING DEF TheLine,TextHeight,TextWidth:INT DEF TextX,TextY:UINT

TheLine$[0]="bottles" TheLine$[1]="of beer on the wall." TheLine$[2]="of beer." TheLine$[3]="Take one down, pass it around."

BottlesOfBeer=99 TheLine=1

GETSCREENSIZE(ScreenSizeX,ScreenSizeY)

WINDOW Win,0,0,ScreenSizeX,ScreenSizeY,@MINBOX|@MAXBOX|@SIZE,0,"99 Bottles Of Beer",MainHandler

GETTEXTSIZE(Win,TheLine$[3],TextWidth,TextHeight)

Erase$=STRING$(TextWidth," ")

PRINT Win,"Let's sing a song."

VSpace(2)

'1.2 seconds. STARTTIMER Win,1200

GOSUB Sing

WAITUNTIL Close=1

CLOSEWINDOW Win

END

SUB MainHandler

    SELECT @CLASS
    CASE @IDCLOSEWINDOW
    Close=1
    CASE @IDTIMER
    GOSUB Sing
    ENDSELECT

RETURN

SUB Sing

    DEF Sing:INT
    Sing=TheLine
    MOVE Win,TextX,TextY
    Number$=STR$(BottlesOfBeer)
    IF BottlesOfBeer=0
         Number$="No more"

TheLine$[0]="bottles" TheLine$[3]="Go to the store and buy some more."

    ENDIF
    IF BottlesOfBeer=1 

TheLine$[0]="bottle" TheLine$[3]="Take it down, pass it around."

    ENDIF
    IF TheLine=4 THEN Sing=1
    IF (TheLine=1)|(TheLine=2)|(TheLine=4)

IF BottlesOfBeer>-1 THEN PRINT Win,Number$+" "+TheLine$[0]+" "+TheLine$[Sing] ELSE GOSUB TheEnd

    ELSE

PRINT Win,TheLine$[3]

BottlesOfBeer=BottlesOfBeer-1

    ENDIF	
    TheLine=TheLine+1
    VSpace(1)
    IF TheLine>4
          TheLine=1

VSpace(1)

    ENDIF

RETURN

SUB TheEnd

    PRINT Win,"What's the problem, offishur?"
    STOPTIMER Win
    VSpace(2)
    MOVE Win,TextX,TextY:PRINT Win,"That's all."

RETURN

SUB VSpace(Number:UINT)

    TextY=TextY+(TextHeight*Number)
    IF TextY+(TextHeight*8)>ScreenSizeY THEN CLR()

RETURN

SUB CLR()

    FOR X=0 TO ScreenSizeY
         MOVE Win,0,X:PRINT Win,Erase$
         TextY=8
    NEXT X

RETURN </lang>

console only version

Rather quickly written and dirty. <lang Creative Basic>REM Using the ESC key to exit will not work in console programs under Windows 95/98 or ME.

DECLARE SingWallLn() DECLARE Delay1() DECLARE Delay2() 'To use ESC Key to exit. DECLARE Quit() DECLARE TheEnd()

DEF Bottles:UINT DEF Number$,Again$:STRING

OPENCONSOLE

PRINT"I'm going to sing a song.":PRINT

Delay1()

LABEL StartSong

Bottles=99

DO

    Quit()
    SingWallLn():Delay1()
    PRINT LTRIM$(STR$(Bottles))+Number$+" of beer.":Delay1()
    IF Bottles>0 THEN PRINT"Take one down, pass it around." ELSE PRINT"Take it down, pass it around.":Delay1()
    Bottles=Bottles-1
    SingWallLn()
    Delay2()

PRINT:PRINT

UNTIL Bottles=0

Delay2()

ClS

LABEL Question

INPUT"Sing it again (y or n)?",Again$

SELECT Again$

CASE("y") CASE("Y")

CLS

GOTO StartSong

CASE "n" CASE "N"

CLS

PRINT"Fine, be that way.":Delay2()

TheEnd()

ENDSELECT

PRINT"Sorry, I didn't understand.":PRINT

GOTO Question

'Keep from running into subroutines. END

SUB SingWallLn()

    IF Bottles=1 THEN Number$=" bottle" ELSE Number$=" bottles"
    PRINT LTRIM$(STR$(Bottles))+Number$+" of beer on the wall."

RETURN

SUB Delay1()

    FOR X=1 TO 7000:NEXT X

RETURN

SUB Delay2()

    FOR X=1 TO 1750000:NEXT X

RETURN

SUB Quit()

    'Close program by pressing the ESC key.
    'Will not work in console under Windows 95/98 or ME.
    IF GETKEYSTATE(0x1B) THEN TheEnd()

RETURN

SUB TheEnd()

    CLOSECONSOLE
    END

RETURN </lang>

FBSL

This is a OO version, using FBSL v3.5 Beta <lang qbasic>#AppType Console

Class Wall bottles

Sub Initialize(%n = 99) bottles = n End Sub

Method Denom() if bottles+1 > 1 then return "one" elseif bottles+1 = 1 then return "it" end if End Method

Method StockUp( %n = 99 ) bottles = n End Method

Method TakeOneDown() bottles = bottles - 1 end Method

Method Pluraliser() if bottles > 1 then return "s" else return "" end if end method

Method Sing() print bottles, " bottle", Pluraliser(), " of beer on the wall" print bottles, " bottle", Pluraliser(), " of beer" TakeOneDown() print "take ", Denom(), " down and pass it round" if bottles > 0 then print bottles, " bottle", Pluraliser(), " of beer on the wall" print else print "no more bottles of beer on the wall" print print "no more bottles of beer on the wall" print "no more bottles of beer on the wall" print "go to the store and buy some more" StockUp(99) print bottles, " bottle", Pluraliser(), " of beer on the wall" print end if return bottles End Method

End Class

Dim BeerSong as new Wall(99)

while BeerSong.Sing() <> 99 end while </lang>

Integer BASIC

IMPORTANT NOTE: Integer BASIC was written (and hand-assembled by Woz himself) for the Apple 1 and original Apple 2. The Apple 1 has NO support for lower-case letters, and it was an expensive (and later) option on the Apple 2. The UPPER-CASE output of this example accurately represents the only reasonable solution for those target devices, and therefore cannot be "fixed" for mixed case, only deleted.

<lang Integer BASIC>E000G (APPLE II) E000R (APPLE I) 10 REM ------------------------- 11 REM BEERSONG IN APPLE INTEGER 12 REM BASIC BY BARRYM 2011-8-21 13 REM THANKS : APPLEWIN1.17.2.0 14 REM THANKS ALSO : POM1 0.7B 15 REM ------------------------- 16 REM PRINTS THE COMPLETE UPPER 17 REM CASE LYRICS ON AN APPLE I 18 REM OR AN 'ORIGINAL' APPLE II 19 REM WITH WOZ'S INTEGER BASIC. 20 REM ------------------------- 21 REM THIS BASIC HAS AN UNUSUAL 22 REM 'THEN', WHICH EXECUTES OR 23 REM SKIPS ONE (AND ONLY ONE!) 24 REM STATEMENT. THIS CONFUSED 25 REM US KIDS REGULARLY WHEN WE 26 REM TRIED TRANSLATING INTEGER 27 REM BASIC GAMES TO APPLE$OFT! 30 REM ------------------------- 40 FOR B=99 TO 98 STEP 0: PRINT : FOR W=0 TO 2: IF W<2 THEN 70 50 IF B THEN PRINT "TAKE ONE DOWN AND PASS IT AROUND";:B=B-1 60 IF B+1 THEN 70:B=99: PRINT "GO TO THE STORE AND BUY SOME MORE"; 70 IF W THEN PRINT ",": IF B THEN PRINT B;: IF B=0 THEN PRINT "NO MORE"; 80 PRINT " BOTTLE";: IF B#1 THEN PRINT "S";: PRINT " OF BEER"; 90 IF W#1 THEN PRINT " ON THE WALL";: IF W THEN PRINT ".": NEXT W,B: END RUN</lang>

Liberty BASIC

<lang lb>For bottles = 99 To 1 Step -1

   song$ = song$ + str$(bottles) + " bottle"
   If (bottles > 1) Then song$ = song$ + "s"
   song$ = song$ + " of beer on the wall, " + str$(bottles) + " bottle"
   If (bottles > 1) Then song$ = song$ + "s"
   song$ = song$ + " of beer,"  + chr$(13) + chr$(10) + "Take one down, pass it around, " + str$(bottles - 1) + " bottle"
   If (bottles > 2) Or (bottles = 1) Then song$ = song$ + "s"
   song$ = song$ + " of beer on the wall." + chr$(13) + chr$(10)

Next bottles song$ = song$ + "No more bottles of beer on the wall, no more bottles of beer." _

       + chr$(13) + chr$(10) + "Go to the store and buy some more, 99 bottles of beer on the wall."

Print song$</lang>

OxygenBasic

int    x=99
string cr,tab,pr,bottles,bottlem,remain
cr=chr(13) chr(10)
tab=chr(9)
pr="99 BOTTLES" cr cr
bottles=" bottles "
bottlem=" bottles "
'
for x=99 to 1 step -1
  if x=1
    bottles=" bottle "
    bottlem=" bottles "
    remain="No"
  elseif x=2
    bottlem=" bottle "
    remain=x-1
  else
    remain=x-1
  end if
  pr+=
  x bottles      "of beer on the wall" cr + 
  x bottles      "of beer" cr +
                 "Take one down, pass it around" cr +
  remain bottlem "of beer on the wall" cr +
  cr
next
'
putfile "t.txt",pr 

PureBasic

Normal version

<lang PureBasic>If OpenConsole()

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

EndIf</lang>

An object-oriented solution

<lang PureBasic>Prototype Wall_Action(*Self, Number.i)

Structure WallClass

 Inventory.i
 AddBottle.Wall_Action
 DrinkAndSing.Wall_Action

EndStructure

Procedure.s _B(n, Short=#False)

 Select n
   Case 0 : result$="No more bottles "
   Case 1 : result$=Str(n)+" bottle of beer"
   Default: result$=Str(n)+" bottles of beer"
 EndSelect
 If Not Short: result$+" on the wall": EndIf
 ProcedureReturn result$+#CRLF$

EndProcedure

Procedure PrintBottles(*Self.WallClass, n)

 Bottles$=" bottles of beer "
 Bottle$ =" bottle of beer "
 txt$ = _B(*Self\Inventory)
 txt$ + _B(*Self\Inventory, #True)
 txt$ + "Take one down, pass it around"+#CRLF$
 *Self\AddBottle(*Self, -1)
 txt$ + _B(*self\Inventory)
 PrintN(txt$)
 ProcedureReturn *Self\Inventory

EndProcedure

Procedure AddBottle(*Self.WallClass, n)

 i=*Self\Inventory+n
 If i>=0
   *Self\Inventory=i
 EndIf

EndProcedure

Procedure InitClass()

 *class.WallClass=AllocateMemory(SizeOf(WallClass))
 If *class
   InitializeStructure(*class, WallClass)
   With *class
     \AddBottle    =@AddBottle()
     \DrinkAndSing =@PrintBottles()
   EndWith
 EndIf
 ProcedureReturn *class

EndProcedure

If OpenConsole()

 *MyWall.WallClass=InitClass()
 If *MyWall
   *MyWall\AddBottle(*MyWall, 99)
   While *MyWall\DrinkAndSing(*MyWall, #True): Wend
   ;
   PrintN(#CRLF$+#CRLF$+"Press ENTER to exit"):Input()
   CloseConsole()
 EndIf

EndIf</lang>

REALbasic

Place the following in the "open" event of a console application. <lang vb>dim bottles as Integer = 99 While bottles > 0

  Print(str(bottles) + " bottles of beer on the wall")
  Print(str(bottles) + " bottles of beer")
  Print("Take one down, pass it around")
  bottles = bottles - 1
  Print(str(bottles) + " bottles of beer on the wall")

Wend</lang>

Run BASIC

<lang Runbasic>b$ = " bottles" for bottles = 99 To 1 Step -1

  If (bottles = 1) then b$ = " bottle"
  print  bottles;b$;" of beer on the wall, "
  print bottles ;b$;" of beer"
  print "Take one down, pass it around, "
  if bottles = 1 then 
     print "No bottles of beer on the wall"
  else
     print bottles - 1;b$;" of beer on the wall.";chr$(10)
  end if

next bottles</lang>

TI-83 BASIC

<lang ti83b>PROGRAM:BEER

For(I,99,1,-1)
Disp I
Disp "BOTTLES OF BEER"
Disp "ON THE WALL,"
Disp I
Pause "BOTTLES OF BEER,"
Disp "TAKE ONE DOWN,"
Disp "PASS IT AROUND,"
Disp I-1
Disp "BOTTLES OF BEER"
Disp "ON THE WALL."
End

</lang>

TI-89 BASIC

<lang ti89b>Prgm

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

EndPrgm</lang>

Visual Basic

<lang vb>Sub Main()

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

End Sub</lang>

Visual Basic .NET

Platform: .NET <lang vbnet>Module Module1

  Sub Main()
      Dim Bottles As Integer
      For Bottles = 99 To 0 Step -1
          If Bottles = 0 Then
              Console.WriteLine("No more bottles of beer on the wall, no more bottles of beer.")
              Console.WriteLine("Go to the store and buy some more, 99 bottles of beer on the wall.")
              Console.ReadLine()
          ElseIf Bottles = 1 Then
              Console.WriteLine(Bottles & " bottle of beer on the wall, " & Bottles & " bottle of beer.")
              Console.WriteLine("Take one down and pass it around, no more bottles of beer on the wall.")
              Console.ReadLine()
          Else
              Console.WriteLine(Bottles & " bottles of beer on the wall, " & Bottles & " bottles of beer.")
              Console.WriteLine("Take one down and pass it around, " & (Bottles - 1) & " bottles of beer on the wall.")
              Console.ReadLine()
          End If
      Next
  End Sub

End Module</lang>

Batch File

<lang dos>@echo off setlocal

main

for /L %%i in (99,-1,1) do ( call :verse %%i ) echo no bottles of beer on the wall echo no bottles of beer echo go to the store and buy some more echo 99 bottles of beer on the wall echo. set /p q="Keep drinking? " if %q% == y goto main if %q% == Y goto main goto :eof

verse

call :plural %1 res echo %res% of beer on the wall echo %res% of beer call :oneit %1 res echo take %res% down and pass it round set /a c=%1-1 call :plural %c% res echo %res% of beer on the wall echo. goto :eof

plural

if %1 gtr 1 goto :gtr if %1 equ 1 goto :equ set %2=no bottles goto :eof

gtr

set %2=%1 bottles goto :eof

equ

set %2=1 bottle goto :eof

oneit

if %1 equ 1 ( set %2=it ) else ( set %2=one ) goto :eof</lang>

Befunge

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

<lang befunge><v <.g10" bottles of beer on the wall"+*4310 < c>:,|

   <v  <.g10" bottles of beer"+*4310
    >:,|
       <v  <"take one down, pass it around"+*4310
        >:,|
           >01g1-:01p                      v

v <.g10" bottles of beer on the wall"+*4310< >:,|

  >134*+0`                                       |
                                                 @</lang>

Bracmat

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

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

Code to save to BottlesOfBeer.bra: <lang bracmat>{BottlesOfBeer.bra

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

X=

 new

= n upper nbottles lyrics

 .   99:?n
   & ( upper
     = .@(!arg:%@?a ?z)&str$(upp$!a !z)
     )
   & ( nbottles
     =   
       .   str
         $ ( (   !arg:>0
               &   !arg
                   " bottle"
                   (!arg:1&|s)
             | "no more bottles"
             )
             " of beer"
           )
     )
   & ( lyrics
     =   (upper$(nbottles$!n:?x) " on the wall, " !x ".\n")
         (   !n+-1:?n:~<0
           &   "Take one down and pass it around, "
               nbottles$!n
               " on the wall.

"

               !lyrics
         |   "Go to the store and buy some more, "
             nbottles$99
             " on the wall.

"

         )
     )
   & put$(str$!lyrics);

r=

 get'"BottlesOfBeer.bra"

& rmv$(str$(BottlesOfBeer ".bak")) & ren$("BottlesOfBeer.bra".str$(BottlesOfBeer ".bak")) & put

 $ ( "{BottlesOfBeer.bra

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

"

   , "BottlesOfBeer.bra"
   , NEW
   )

& lst'(X,"BottlesOfBeer.bra",APP) & put'(\n,"BottlesOfBeer.bra",APP) & lst'(r,"BottlesOfBeer.bra",APP) & put$(str$("\nnew'" X ";\n"),"BottlesOfBeer.bra",APP);

new'X; </lang>

Brainf***

<lang bf>>+++++++++[<+++++++++++>-]<[>[-]>[-]<<[>+>+<<-]>>[<<+>>-]>>> [-]<<<+++++++++<[>>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+< -]<<-<-]+++++++++>[<->-]>>+>[<[-]<<+>>>-]>[-]+<<[>+>-<<-]<<< [>>+>+<<<-]>>>[<<<+>>>-]>[<+>-]<<-[>[-]<[-]]>>+<[>[-]<-]<+++ +++++[<++++++<++++++>>-]>>>[>+>+<<-]>>[<<+>>-]<[<<<<<.>>>>>- ]<<<<<<.>>[-]>[-]++++[<++++++++>-]<.>++++[<++++++++>-]<++.>+ ++++[<+++++++++>-]<.><+++++..--------.-------.>>[>>+>+<<<-]> >>[<<<+>>>-]<[<<<<++++++++++++++.>>>>-]<<<<[-]>++++[<+++++++ +>-]<.>+++++++++[<+++++++++>-]<--.---------.>+++++++[<------


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

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


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

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


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

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


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

.>>>>-]<<<<[-]>++++[<++++++++>-]<.>+++++++++[<+++++++++>-]<- -.---------.>+++++++[<---------->-]<.>++++++[<+++++++++++>-] <.+++..+++++++++++++.>++++++++[<---------->-]<--.>+++++++++[ <+++++++++>-]<--.-.>++++++++[<---------->-]<++.>++++++++[<++ ++++++++>-]<++++.------------.---.>+++++++[<---------->-]<+. >++++++++[<+++++++++++>-]<-.>++[<----------->-]<.+++++++++++ ..>+++++++++[<---------->-]<-----.---.+++.---.[-]<<<]</lang>

Brat

<lang brat>99.to 2 { n |

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

}

p "One bottle of beer on the wall, one bottle of beer!" p "Take one down, pass it around, no more bottles of beer on the wall."</lang>

C

Translation of: C++

The simple solution

<lang c>#include <stdlib.h>

  1. include <stdio.h>

int main(void) {

 unsigned int bottles = 99;
 do
 {
   printf("%u bottles of beer on the wall\n", bottles);
   printf("%u bottles of beer\n", bottles);
   printf("Take one down, pass it around\n");
   printf("%u bottles of beer on the wall\n\n", --bottles);
 } while(bottles > 0);
 return EXIT_SUCCESS;

}</lang>

Code golf

<lang c>#include <stdio.h> main(){_=100;while(--_)printf("%i bottle%s of beer in the wall,\n%i bottle%" "s of beer.\nTake one down, pass it round,\n%s%s\n\n",_,_-1?"s":"",_,_-1?"s"

"",_-1?(char[]){(_-1)/10?(_-1)/10+48:(_-1)%10+48,(_-1)/10?(_-1)%10+48:2+30,

(_-1)/10?32:0,0}:"",_-1?"bottles of beer in the wall":"No more beers");}</lang>

A preprocessor solution

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

<lang c>#include <stdlib.h>

  1. include <stdio.h>
  1. define BOTTLE(nstr) nstr " bottles of beer"
  1. define WALL(nstr) BOTTLE(nstr) " on the wall"
  1. define PART1(nstr) WALL(nstr) "\n" BOTTLE(nstr) \
                   "\nTake one down, pass it around\n"
  1. define PART2(nstr) WALL(nstr) "\n\n"
  1. define MIDDLE(nstr) PART2(nstr) PART1(nstr)
  1. define SONG PART1("100") CD2 PART2("0")
  1. define CD2 CD3("9") CD3("8") CD3("7") CD3("6") CD3("5") \
       CD3("4") CD3("3") CD3("2") CD3("1") CD4("")
  1. define CD3(pre) CD4(pre) MIDDLE(pre "0")
  1. define CD4(pre) MIDDLE(pre "9") MIDDLE(pre "8") MIDDLE(pre "7") \
MIDDLE(pre "6") MIDDLE(pre "5") MIDDLE(pre "4") MIDDLE(pre "3") \
MIDDLE(pre "2") MIDDLE(pre "1")

int main(void) {

 (void) printf(SONG);
 return EXIT_SUCCESS;

}</lang>

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

The bottled version

WYSIWYG (with correct plurals and can buy some more):<lang c> int b =99,u =1;

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

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

int main() {return p(0);}</lang>

C++

The simple solution

<lang cpp>#include <iostream> using namespace std;

int main() {

int bottles = 99;
  do {
    cout << bottles << " bottles of beer on the wall" << endl;
    cout << bottles << " bottles of beer" << endl;
    cout << "Take one down, pass it around" << endl;
    cout << --bottles << " bottles of beer on the wall\n" << endl;
  } while (bottles > 0);

}</lang>

An object-oriented solution

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

A template metaprogramming solution

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

<lang cpp>#include <iostream>

template<int max, int min> struct bottle_countdown {

 static const int middle = (min + max)/2;
 static void print()
 {
   bottle_countdown<max, middle+1>::print();
   bottle_countdown<middle, min>::print();
 }

};

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

 static void print()
 {
   std::cout << value << " bottles of beer on the wall\n"
             << value << " bottles of beer\n"
             << "Take one down, pass it around\n"
             << value-1 << " bottles of beer\n\n";
 }

};

int main() {

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

}</lang>

A Recursive solution

<lang cpp>#include <iostream> using namespace std; void rec(int bottles) { if ( bottles!=0)

{    
    cout << bottles << " bottles of beer on the wall" << endl; 
       cout << bottles << " bottles of beer" << endl;
       cout << "Take one down, pass it around" << endl; 
       cout << --bottles << " bottles of beer on the wall\n" << endl;    
   rec(bottles);
}  

}

int main()

{   

rec(99); system("pause"); return 0; } </lang>

A preprocessor solution

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

<lang cpp>#include <iostream>

  1. include <ostream>
  1. define BOTTLE(nstr) nstr " bottles of beer"
  1. define WALL(nstr) BOTTLE(nstr) " on the wall"
  1. define PART1(nstr) WALL(nstr) "\n" BOTTLE(nstr) \
                   "\nTake one down, pass it around\n"
  1. define PART2(nstr) WALL(nstr) "\n\n"
  1. define MIDDLE(nstr) PART2(nstr) PART1(nstr)
  1. define SONG PART1("100") CD2 PART2("0")
  1. define CD2 CD3("9") CD3("8") CD3("7") CD3("6") CD3("5") \
       CD3("4") CD3("3") CD3("2") CD3("1") CD4("")
  1. define CD3(pre) CD4(pre) MIDDLE(pre "0")
  1. define CD4(pre) MIDDLE(pre "9") MIDDLE(pre "8") MIDDLE(pre "7") \
MIDDLE(pre "6") MIDDLE(pre "5") MIDDLE(pre "4") MIDDLE(pre "3") \
MIDDLE(pre "2") MIDDLE(pre "1")

int main() {

 std::cout << SONG;
 return 0;

}</lang>

Bottled Version

<lang cpp> //>,_

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

C#

<lang csharp>using System;

class Program {

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

}</lang>

Another Implementation using Linq

Works with: C# version 3+

<lang csharp>using System; using System.Linq;

class Program {

   static void Main()
   {
       var query = from total in Enumerable.Range(0,100).Reverse()
                   select (total > 0)
                       ? string.Format("{0} bottles of beer on the wall\n{0} bottles of beer\nTake one down, pass it around", total)
                       : string.Format("{0} bottles left", total);
           
       foreach (var item in query)
       {
           Console.WriteLine(item);
       }
   }

}</lang>

Flexible Version

<lang csharp>

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

</lang>

Using Formatting

Works with: C# version 3+

<lang csharp> class songs {

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

}</lang>

OUTPUT: 5 bottles of beer on the wall 5 bottles of beer Take one down, pass it around 4 bottles of beer on the wall

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

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

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

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


Using iterator blocks

Works with: C# version 3+

<lang csharp>using System; using System.Linq;

class Program {

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

}</lang>

A Fun One

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


int bottlesLeft = 99; const int FIRST_LINE_SINGULAR = 98; const int FINAL_LINE_SINGULAR = 97; string firstLine = ""; string finalLine = "";


for (int i = 0; i < 99; i++) { firstLine = bottlesLeft.ToString() + " bottle"; if (i != FIRST_LINE_SINGULAR) firstLine += "s"; firstLine += " of beer on the wall, " + bottlesLeft.ToString() + " bottle"; if (i != FIRST_LINE_SINGULAR) firstLine += "s"; firstLine += " of beer";

Console.WriteLine(firstLine); Console.WriteLine("Take the " + bottles[i] + " down, pass it around,"); bottlesLeft--;

finalLine = bottlesLeft.ToString() + " bottle"; if (i != FINAL_LINE_SINGULAR) finalLine += "s"; finalLine += " of beer on the wall!";

Console.WriteLine(finalLine); Console.WriteLine(); Console.ReadLine(); } </lang>

Clay

<lang Clay>/* A few options here: I could give n type Int; or specify that n is of any

  numeric type; but here I just let it go -- that way it'll work with anything
  that compares with 1 and that printTo knows how to convert to a string. And
  all checked at compile time, remember. */

getRound(n) {

   var s      = String();
   var bottle = if (n == 1) " bottle " else " bottles ";
   
   printTo(s, 
           n, bottle, "of beer on the wall\n",
           n, bottle, "of beer\n",
           "take one down, pass it around\n",
           n, bottle, "of beer on the wall!\n");
   
   return s;

}

main() {

   println(join("\n", mapped(getRound, reversed(range(100)))));

} </lang>

Chapel

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

Works with: Chapel version 1.7.0

<lang Chapel> /***********************************************************************

* Chapel implementation of "99 bottles of beer"
*
* by Brad Chamberlain and Steve Deitz
* 07/13/2006 in Knoxville airport while waiting for flight home from
*            HPLS workshop
* compiles and runs with chpl compiler version 1.7.0
* for more information, contact: chapel_info@cray.com
* 
*
* Notes: 
* o as in all good parallel computations, boundary conditions
*   constitute the vast bulk of complexity in this code (invite Brad to
*   tell you about his zany boundary condition simplification scheme)
* o uses type inference for variables, arguments
* o relies on integer->string coercions
* o uses named argument passing (for documentation purposes only)
***********************************************************************/

// allow executable command-line specification of number of bottles // (e.g., ./a.out -snumBottles=999999) config const numBottles = 99; const numVerses = numBottles+1;

// a domain to describe the space of lyrics var LyricsSpace: domain(1) = {1..numVerses};

// array of lyrics var Lyrics: [LyricsSpace] string;

// parallel computation of lyrics array [verse in LyricsSpace] Lyrics(verse) = computeLyric(verse);

// as in any good parallel language, I/O to stdout is serialized. // (Note that I/O to a file could be parallelized using a parallel // prefix computation on the verse strings' lengths with file seeking) writeln(Lyrics);


// HELPER FUNCTIONS:

proc computeLyric(verseNum) {

 var bottleNum = numBottles - (verseNum - 1);
 var nextBottle = (bottleNum + numVerses - 1)%numVerses;
 return "\n" // disguise space used to separate elements in array I/O
      + describeBottles(bottleNum, startOfVerse=true) + " on the wall, "
      + describeBottles(bottleNum) + ".\n"
      + computeAction(bottleNum)
      + describeBottles(nextBottle) + " on the wall.\n";

}


proc describeBottles(bottleNum, startOfVerse:bool = false) { // NOTE: bool should not be necessary here (^^^^); working around bug

 var bottleDescription = if (bottleNum) then bottleNum:string 
                                        else (if startOfVerse then "N" 
                                                              else "n") 
                                             + "o more";
 return bottleDescription 
      + " bottle" + (if (bottleNum == 1) then "" else "s") 
      + " of beer";

}


proc computeAction(bottleNum) {

 return if (bottleNum == 0) then "Go to the store and buy some more, "
                            else "Take one down and pass it around, ";

} </lang>

Chef

<lang chef>99 Bottles Of Beer.

Ingredients. 99 bottles

Method. Loop the bottles. Put bottles into 1st mixing bowl. Serve with bottles of beer on the wall. Clean 1st mixing bowl. Put bottles into 1st mixing bowl. Serve with bottles of beer. Clean 1st mixing bowl. Serve with Take one down and pass it around. Clean 1st mixing bowl. Loop the bottles until looped. Serve with No more bottles of beer. Clean 1st mixing bowl. Pour contents of the 3rd mixing bowl into the 1st baking dish.

Serves 1.

bottles of beer on the wall.

Prints out "n" bottles of beer on the wall.

Ingredients. 108 g lime 97 cups asparagus 119 pinches watercress 32 tablespoons pickles 101 pinches eggplant 104 g huckleberry 116 teaspoons turnip 110 tablespoons nannyberry 111 tablespoons onion 114 tablespoons raspberry 98 g broccoli 102 g feijoa 115 teaspoons squach 10 ml new line

Method. Put new line into 1st mixing bowl. Put lime into 2nd mixing bowl. Put lime into 2nd mixing bowl. Put asparagus into 2nd mixing bowl. Put watercress into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put huckleberry into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put nannyberry into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put raspberry into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put broccoli into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put feijoa into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put squach into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put lime into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put broccoli into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Liquify contents of the 2nd mixing bowl. Pour contents of the 2nd mixing bowl into the baking dish. Pour contents of the mixing bowl into the baking dish. Refrigerate for 1 hour.

bottles of beer.

Prints out "n" bottles of beer.

Ingredients. 114 tablespoons raspberry 101 pinches eggplant 98 teaspoons broccoli 32 pinches pickles 102 tablespoons feijoa 111 teaspoons onion 115 cups squach 108 cups lime 116 teaspoons turnip 10 ml new line

Method. Put new line into 1st mixing bowl. Put raspberry into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put broccoli into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put feijoa into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put squach into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put lime into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put broccoli into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Liquify contents of the 2nd mixing bowl. Pour contents of the 2nd mixing bowl into the baking dish. Pour contents of the mixing bowl into the baking dish. Refrigerate for 1 hour.

Take one down and pass it around.

Prints out "Take one down and pass it around".

Ingredients. 100 cups dandelion 110 g nannyberry 117 pinches cucumber 111 pinches onion 114 pinches raspberry 97 g asparagus 32 tablespoons pickles 116 pinches turnip 105 g chestnut 115 g squach 112 g pumpkin 119 cups watercress 101 g eggplant 107 g kale 84 cups tomatoe 10 ml new line

Method. Put new line into 3rd mixing bowl. Put dandelion into 2nd mixing bowl. Put nannyberry into 2nd mixing bowl. Put cucumber into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put raspberry into 2nd mixing bowl. Put asparagus into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put chestnut into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put squach into 2nd mixing bowl. Put squach into 2nd mixing bowl. Put asparagus into 2nd mixing bowl. Put pumpkin into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put dandelion into 2nd mixing bowl. Put nannyberry into 2nd mixing bowl. Put asparagus into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put nannyberry into 2nd mixing bowl. Put watercress into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put dandelion into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put nannyberry into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put kale into 2nd mixing bowl. Put asparagus into 2nd mixing bowl. Put tomatoe into 2nd mixing bowl. Liquify contents of the 2nd mixing bowl. Pour contents of the 2nd mixing bowl into the baking dish. Pour contents of the 3rd mixing bowl into the baking dish. Refrigerate for 1 hour.

No more bottles of beer.

Prints out "No more bottles of beer".

Ingredients. 114 pinches raspberry 101 teaspoons eggplant 98 cups broccoli 32 tablespoons pickles 102 pinches feijoa 111 cups onion 115 tablespoons squach 108 tablespoons lime 116 pinches turnip 109 cups mushrooms 78 g nectarine 10 ml new line

Method. Put new line into 3rd mixing bowl. Put new line into 2nd mixing bowl. Put raspberry into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put broccoli into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put feijoa into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put squach into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put lime into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put turnip into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put broccoli into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put eggplant into 2nd mixing bowl. Put raspberry into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put mushrooms into 2nd mixing bowl. Put pickles into 2nd mixing bowl. Put onion into 2nd mixing bowl. Put nectarine into 2nd mixing bowl. Liquify contents of the 2nd mixing bowl. Pour contents of the 2nd mixing bowl into the baking dish. Pour contents of the 3rd mixing bowl into the baking dish. Refrigerate for 1 hour.</lang>

CLIPS

<lang clips>(deffacts beer-bottles

 (bottles 99))

(deffunction bottle-count

 (?count)
 (switch ?count
   (case 0 then "No more bottles of beer")
   (case 1 then "1 more bottle of beer")
   (default (str-cat ?count " bottles of beer"))))

(defrule stanza

 ?bottles <- (bottles ?count)
 =>
 (retract ?bottles)
 (printout t (bottle-count ?count) " on the wall," crlf)
 (printout t (bottle-count ?count) "." crlf)
 (printout t "Take one down, pass it around," crlf)
 (printout t (bottle-count (- ?count 1)) " on the wall." crlf crlf)
 (if (> ?count 1) then (assert (bottles (- ?count 1)))))</lang>

Clojure

<lang lisp>(defn verse

 [n]
 (printf "%d bottles of beer on the wall,

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

         n
         n
         (dec n)))

(defn sing

 [start]
 (doseq [n (range start 0 -1)]
   (verse n)))

(sing 99)</lang>

COBOL

Works with: OpenCOBOL version 1.1

Free form version. <lang cobol>identification division. program-id. ninety-nine. environment division. data division. working-storage section. 01 counter pic 99. 88 no-bottles-left value 0. 88 one-bottle-left value 1.

01 parts-of-counter redefines counter. 05 tens pic 9. 05 digits pic 9.

01 after-ten-words. 05 filler pic x(7) value spaces. 05 filler pic x(7) value "Twenty". 05 filler pic x(7) value "Thirty". 05 filler pic x(7) value "Forty". 05 filler pic x(7) value "Fifty". 05 filler pic x(7) value "Sixty". 05 filler pic x(7) value "Seventy". 05 filler pic x(7) value "Eighty". 05 filler pic x(7) value "Ninety". 05 filler pic x(7) value spaces.

01 after-ten-array redefines after-ten-words. 05 atens occurs 10 times pic x(7).

01 digit-words. 05 filler pic x(9) value "One". 05 filler pic x(9) value "Two". 05 filler pic x(9) value "Three". 05 filler pic x(9) value "Four". 05 filler pic x(9) value "Five". 05 filler pic x(9) value "Six". 05 filler pic x(9) value "Seven". 05 filler pic x(9) value "Eight". 05 filler pic x(9) value "Nine". 05 filler pic x(9) value "Ten". 05 filler pic x(9) value "Eleven". 05 filler pic x(9) value "Twelve". 05 filler pic x(9) value "Thirteen". 05 filler pic x(9) value "Fourteen". 05 filler pic x(9) value "Fifteen". 05 filler pic x(9) value "Sixteen". 05 filler pic x(9) value "Seventeen". 05 filler pic x(9) value "Eighteen". 05 filler pic x(9) value "Nineteen". 05 filler pic x(9) value spaces.

01 digit-array redefines digit-words. 05 adigits occurs 20 times pic x(9).

01 number-name pic x(15).

procedure division. 100-main section. 100-setup. perform varying counter from 99 by -1 until no-bottles-left perform 100-show-number display " of beer on the wall" perform 100-show-number display " of beer" display "Take " with no advancing if one-bottle-left display "it " with no advancing else display "one " with no advancing end-if display "down and pass it round" subtract 1 from counter giving counter perform 100-show-number display " of beer on the wall" add 1 to counter giving counter display space end-perform. display "No more bottles of beer on the wall" display "No more bottles of beer" display "Go to the store and buy some more" display "Ninety Nine bottles of beer on the wall" stop run.

100-show-number. if no-bottles-left display "No more" with no advancing else if counter < 20 display function trim( adigits( counter ) ) with no advancing else if counter < 100 move spaces to number-name string atens( tens ) delimited by space, space delimited by size, adigits( digits ) delimited by space into number-name display function trim( number-name) with no advancing end-if end-if end-if. if one-bottle-left display " bottle" with no advancing else display " bottles" with no advancing end-if.

100-end. end-program.</lang>

Another free-form version, without using DISPLAY NO ADVANCING. <lang cobol>identification division. program-id. ninety-nine. environment division. data division. working-storage section. 01 counter pic 99. 88 no-bottles-left value 0. 88 one-bottle-left value 1.

01 parts-of-counter redefines counter. 05 tens pic 9. 05 digits pic 9.

01 after-ten-words. 05 filler pic x(7) value spaces. 05 filler pic x(7) value "Twenty". 05 filler pic x(7) value "Thirty". 05 filler pic x(7) value "Forty". 05 filler pic x(7) value "Fifty". 05 filler pic x(7) value "Sixty". 05 filler pic x(7) value "Seventy". 05 filler pic x(7) value "Eighty". 05 filler pic x(7) value "Ninety". 05 filler pic x(7) value spaces.

01 after-ten-array redefines after-ten-words. 05 atens occurs 10 times pic x(7).

01 digit-words. 05 filler pic x(9) value "One". 05 filler pic x(9) value "Two". 05 filler pic x(9) value "Three". 05 filler pic x(9) value "Four". 05 filler pic x(9) value "Five". 05 filler pic x(9) value "Six". 05 filler pic x(9) value "Seven". 05 filler pic x(9) value "Eight". 05 filler pic x(9) value "Nine". 05 filler pic x(9) value "Ten". 05 filler pic x(9) value "Eleven". 05 filler pic x(9) value "Twelve". 05 filler pic x(9) value "Thirteen". 05 filler pic x(9) value "Fourteen". 05 filler pic x(9) value "Fifteen". 05 filler pic x(9) value "Sixteen". 05 filler pic x(9) value "Seventeen". 05 filler pic x(9) value "Eighteen". 05 filler pic x(9) value "Nineteen". 05 filler pic x(9) value spaces.

01 digit-array redefines digit-words. 05 adigits occurs 20 times pic x(9).

01 number-name pic x(15).

01 stringified pic x(30). 01 outline pic x(50). 01 other-numbers. 03 n pic 999. 03 r pic 999.

procedure division. 100-main section. 100-setup. perform varying counter from 99 by -1 until no-bottles-left move spaces to outline perform 100-show-number string stringified delimited by "|", space, "of beer on the wall" into outline end-string display outline end-display move spaces to outline string stringified delimited by "|", space, "of beer" into outline end-string display outline end-display move spaces to outline move "Take" to outline if one-bottle-left string outline delimited by space, space, "it" delimited by size, space, "|" into outline end-string else string outline delimited by space, space, "one" delimited by size, space, "|" into outline end-string end-if string outline delimited by "|", "down and pass it round" delimited by size into outline end-string display outline end-display move spaces to outline subtract 1 from counter giving counter end-subtract perform 100-show-number string stringified delimited by "|", space, "of beer on the wall" into outline end-string display outline end-display add 1 to counter giving counter end-add display space end-display end-perform. display "No more bottles of beer on the wall" display "No more bottles of beer" display "Go to the store and buy some more" display "Ninety-Nine bottles of beer on the wall" stop run.

100-show-number. if no-bottles-left move "No more|" to stringified else if counter < 20 string function trim( adigits( counter ) ), "|" into stringified else if counter < 100 move spaces to number-name string atens( tens ) delimited by space, space delimited by size, adigits( digits ) delimited by space into number-name end-string move function trim( number-name) to stringified divide counter by 10 giving n remainder r end-divide if r not = zero inspect stringified replacing first space by "-" end-if inspect stringified replacing first space by "|" end-if end-if end-if. if one-bottle-left string stringified delimited by "|", space, "bottle|" delimited by size into stringified end-string else string stringified delimited by "|", space, "bottles|" delimited by size into stringified end-string end-if.

100-end. end-program.</lang>

A more concise version that adheres to the minimum guidelines. Leading zeros are not suppressed. (OpenCOBOL - 1.1.0) <lang cobol>program-id. ninety-nine. data division. working-storage section. 01 cnt pic 99.

procedure division.

 perform varying cnt from 99 by -1 until cnt < 1
   display cnt " bottles of beer on the wall"
   display cnt " bottles of beer"
   display "Take one down, pass it around"
   subtract 1 from cnt 
   display cnt " bottles of beer on the wall"
   add 1 to cnt
   display space
 end-perform.</lang>

CoffeeScript

<lang coffeescript> bottlesOfBeer = (n) ->

 "#{n} bottle#{if n is 1 then  else 's'} of beer"

console.log """

 #{bottlesOfBeer n} on the wall
 #{bottlesOfBeer n}
 Take one down, pass it around
 #{bottlesOfBeer n - 1} on the wall
 \n""" for n in [99..1]

</lang>

With completely different approach...

<lang coffeescript>for j in [99..1]

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

</lang>

or as a one liner...

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

or another completely different one liner

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

ColdFusion

Classic tag based CFML

<lang cfm><cfoutput>

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

</cfloop>

</cfoutput></lang> or if you prefer: (identical output, grammatically correct to the last stanza)

CFScript

<lang cfm><cfscript>

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

");
}

</cfscript></lang>

Common Lisp

Sensible solution

<lang lisp>(defun bottles (x)

 (loop for bottles from x downto 1
       do (format t "~a bottle~:p of beer on the wall

~:*~a bottle~:p of beer Take one down, pass it around ~a bottle~:p of beer on the wall~2%" bottles (1- bottles))))</lang> and then just call <lang lisp>(bottles 99)</lang>

Ridiculous

<lang lisp>(format t "~{~[~^~]~:*~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%~}"

         (loop :for n :from 99 :downto 0 :collect n))</lang>

The FORMAT function is probably the most baroque (i.e. featureful almost to a fault) function in Common Lisp. To really drive this point home, try replacing each instance of ~D with ~R, and then with ~@R. Yes, this is all standard and dependable (dys?)functionality.

Explanation of the format string for the uninitiated:

  • ~{fmt~} expects the next argument to be a list (which is of the integers from 99 down to 0), and executes the format string fmt on each element. It is essentially a map or foreach.
  • ~[...~] is a case/switch. It executes the nth clause, where n is taken from the next argument. Since there is only one clause here, it will be executed only when the argument is 0.
  • ~^ will terminate formatting.
  • ~:* will back-up to the most-recently used argument.
  • ~D prints the next argument as a decimal number.
  • ~:P is for English plurals: it prints s if the last argument wasn't 1; it prints nothing otherwise. There's also ~@P for y/ies, in case you were worried about that.

Note, by the way, how the emoticons :*~D and :P have shown up in the format string. FORMAT is so powerful, it's even self-aware about how silly it is.

Component Pascal

BlackBox Component Builder <lang oberon2> MODULE BottlesOfBeer; IMPORT StdLog; CONST bottles = 99;

PROCEDURE Part(i: INTEGER); BEGIN StdLog.Int(i);StdLog.String(" bottles of beer on the wall");StdLog.Ln; StdLog.Int(i);StdLog.String(" bottles of beer");StdLog.Ln; StdLog.String("Take one down, pass it around");StdLog.Ln; StdLog.Int(i - 1);StdLog.String(" bottles of beer on the wall.");StdLog.Ln; StdLog.Ln END Part;

PROCEDURE Sing*; VAR i: INTEGER; BEGIN FOR i := bottles TO 1 BY -1 DO Part(i) END END Sing; END BottlesOfBeer. </lang> Execute: ^Q BottlesOfBeer.Sing
Output:

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

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

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

...


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

D

Simple Solution

Works with: D version 2

Based on Steward Gordon's code at: 99-bottles-of-beer.net. <lang d>import std.stdio;

void main() {

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

}</lang>

CTFE Solution

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

<lang d>import std.stdio, std.conv;

string bottles(in size_t num) pure {

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

}

pragma(msg, 99.bottles); void main() {}</lang>

Dart

<lang dart>main() {

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

}</lang>

Delphi

See Pascal
Or

<lang Delphi>program Hundred_Bottles;

{$APPTYPE CONSOLE}

uses SysUtils;

const C_1_Down = 'Take one down, pass it around' ;

Var i : Integer ;

// As requested, some fun : examples of Delphi basic techniques. Just to make it a bit complex

procedure WriteABottle( BottleNr : Integer ) ; begin

 Writeln(BottleNr, ' bottles of beer on the wall' ) ; 

end ;

begin

 for i := 99 Downto 1 do begin 
 WriteABottle(i); 
 Writeln( Format('%d bottles of beer' , [i] ) ) ; 
 Writeln( C_1_Down ) ; 
 WriteABottle(i-1); 
 Writeln ; 

End ;

end.</lang>

Déjà Vu

<lang dejavu>plural i: if = 1 i "" "s"

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

bottles 99</lang>

Dylan

<lang dylan>Module: bottles define method bottles (n :: <integer>)

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

end method</lang>

E

<lang e>def bottles(n) {

 return switch (n) {
   match ==0 { "No bottles" }
   match ==1 { "1 bottle" }
   match _   { `$n bottles` }
 }

} for n in (1..99).descending() {

 println(`${bottles(n)} of beer on the wall,

${bottles(n)} of beer. Take one down, pass it around, ${bottles(n.previous())} of beer on the wall. `) }</lang>

ECL

<lang ECL> Layout := RECORD

 UNSIGNED1 RecID1;
 UNSIGNED1 RecID2;
 STRING30  txt;

END; Beers := DATASET(99,TRANSFORM(Layout,

                             SELF.RecID1 := COUNTER,SELF.RecID2 := 0,SELF.txt := ));

Layout XF(Layout L,INTEGER C) := TRANSFORM

 IsOneNext := L.RecID1-1 = 1;
 IsOne := L.RecID1 = 1;
 SELF.txt := CHOOSE(C,
                    (STRING)(L.RecID1-1) + ' bottle'+IF(IsOneNext,,'s')+' of beer on the wall',
                    'Take one down, pass it around',
                    (STRING)(L.RecID1) + ' bottle'+IF(IsOne,,'s')+' of beer',
                    (STRING)(L.RecID1) + ' bottle'+IF(IsOne,,'s')+' of beer on the wall',);
 SELF.RecID2 := C;
 SELF := L;

END;

Rev := NORMALIZE(Beers,5,XF(LEFT,COUNTER)); OUTPUT(SORT(Rev,-Recid1,-RecID2),{txt},ALL); </lang>

EGL

<lang EGL>program TestProgram type BasicProgram {}

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

end</lang>

Eiffel

<lang eiffel> class APPLICATION

create make

feature {NONE} -- Initialization

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

end </lang>

Ela

<lang Ela>open list

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

        ++ show v                 
        ++" bottles of beer\nTake one down, pass it around\n"

map beer [99,98..0]</lang>

Elixir

<lang Elixir>defmodule Bottles do

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

end

Bottles.run</lang>

Erlang

<lang erlang>-module(beersong). -export([sing/0]). -define(TEMPLATE_0, "~s of beer on the wall, ~s of beer.~nGo to the store and buy some more, 99 bottles of beer on the wall.~n"). -define(TEMPLATE_N, "~s of beer on the wall, ~s of beer.~nTake one down and pass it around, ~s of beer on the wall.~n~n").

create_verse(0) -> {0, io_lib:format(?TEMPLATE_0, phrase(0))}; create_verse(Bottle) -> {Bottle, io_lib:format(?TEMPLATE_N, phrase(Bottle))}.

phrase(0) -> ["No more bottles", "no more bottles"]; phrase(1) -> ["1 bottle", "1 bottle", "no more bottles"]; phrase(2) -> ["2 bottles", "2 bottles", "1 bottle"]; phrase(Bottle) -> lists:duplicate(2, integer_to_list(Bottle) ++ " bottles") ++ [integer_to_list(Bottle-1) ++ " bottles"].

bottles() -> lists:reverse(lists:seq(0,99)).

sing() ->

   lists:foreach(fun spawn_singer/1, bottles()),
   sing_verse(99).

spawn_singer(Bottle) ->

   Pid = self(), 
   spawn(fun() -> Pid ! create_verse(Bottle) end).

sing_verse(Bottle) ->

   receive
       {_, Verse} when Bottle == 0 ->
           io:format(Verse);
       {N, Verse} when Bottle == N ->
           io:format(Verse),
           sing_verse(Bottle-1)
   after 
       3000 ->
           io:format("Verse not received - re-starting singer~n"),
           spawn_singer(Bottle),
           sing_verse(Bottle)
   end.</lang>

Euphoria

Works with: Euphoria version 4.0.0

This is based on the Batch File example. <lang Euphoria> include std/console.e include std/search.e

function one_or_it( atom n ) if n = 1 then return "it" else return "one" end if end function

function numberable( atom n ) if n = 0 then return "no" else return sprintf( "%d", n ) end if end function

function plural( atom n ) if n != 1 then return "s" else return "" end if end function

atom stillDrinking = 1

sequence yn sequence plurality sequence numerality

while stillDrinking do for bottle = 99 to 1 by -1 do plurality = plural( bottle ) numerality = numberable( bottle ) printf( 1, "%s bottle%s of beer on the wall\n%s bottle%s of beer\n", { numerality, plurality, numerality, plurality } ) printf( 1, "Take %s down and pass it round\n", { one_or_it( bottle ) } ) printf( 1, "%s bottle%s of beer on the wall\n\n", { numberable( bottle - 1 ), plural( bottle - 1 ) } ) end for puts( 1, "No more bottles of beer on the wall\nNo more bottles of beer\n" ) puts( 1, "Go to the store and buy some more\n99 bottles of beer on the wall\n" ) puts( 1, "\nKeep drinking? " ) yn = gets(0) stillDrinking = find_any( "yY", yn ) puts( 1, "\n" ) end while</lang>

Extended BrainF***

more info about EBF <lang ebf>

Macroes
create 100

{init

 :tmp
 $tmp 10+(-^where 10+)
 !tmp

}

macro that prints 99-2

{print_num

 :what:div:1s:10s
 %where(-$what+$div+)
 $div(-^where+)
 %div 10+
 $what &divmod
 $div(-)
 $10s(|"0"(-))
 $1s|"0"(-)
 $what(-)
 !10s!1s!div!what

}

macro that prints the text between the numbers

{do_iteration

   :iter:zero:tmp
   (-$iter+$zero+)
   $zero(-^+)+
   switch $iter-
   (
     $tmp|" of beer on the wall"(-)
     $iter-
     (-$zero-|"."(-)10+..(-))
     $zero(-|", "(-))
   )
   $zero(-
           |" of beer."(-)10+.(-)
           $zero+
           $not_first((-)$zero-
               |"Go to the store and buy some more, 99 bottles of beer on the wall."(-)10+.(-))
           $zero(-|"Take one down and pass it around, "(-))
   )
 !tmp!zero!iter

}

divmod performs divide and modulus at the same time

{divmod[->-[>+>>]>[+[-<+>]>+>>]<<<<<]*-3}

global variables
not_first
round
number
copy
flag
main program starts here

$number &init while $number (

 $round++
 $not_first(-$round+)
 while $round
 (
   $number(-$copy+$flag+)
   $flag(-$number+)+
   switch $copy
   -(-
     (+
       $copy &print_num
       $flag-
       $copy(-)
       |" bottles"(-)
     ) $flag (-
         |"1 bottle"(-)
   )) $flag (-
         |"No more bottles"(-)
         $not_first+
   )
   $round &do_iteration
   $round-
 )
 $not_first+
 $number-

)

</lang>


F#

<lang fsharp>#light let rec bottles n =

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

Factor

<lang factor>USING: io kernel make math math.parser math.ranges sequences ;

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

! Usage: 99 bottles</lang>

Falcon

<lang falcon>for i in [99:1]

> i, " bottles of beer on the wall"
> i, " bottles of beer"
> "Take one down, pass it around"
> i-1, " bottles of beer on the wall\n"

end</lang>

A more robust version to handle plural/not plural conditions <lang falcon>for i in [99:1]

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

end</lang>

FALSE

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

ferite

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

<lang ferite>uses "console";

number bottles = 99; boolean looping = true; object counter = closure { if (--bottles > 0) { return true; } else { return false; } };

while (looping) { Console.println("${bottles} bottles of beer on the wall,"); Console.println("${bottles} bottles of beer,"); Console.println("Take one down, pass it around,");

looping = counter.invoke();

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

Fexl

<lang fexl> \bottles_of_beer =

   (\n
   print (< n 1 "No more" n);
   print " bottle"; print (== n 1 "" "s");
   print " of beer";
   )

\bottles_of_beer_on_the_wall =

   (\n
   bottles_of_beer n; print " on the wall";
   )

\sing_bottles_of_beer =

   (\max
   do (range max 0) \qty
   bottles_of_beer_on_the_wall qty; nl;
   bottles_of_beer qty; nl;
   \qty =
       (
       > qty 0
           (
           print "Take one down, pass it around";nl;
           - qty 1
           )
           (
           print "Go to the store and buy some more";nl;
           max
           )
       )
   bottles_of_beer_on_the_wall qty; nl; 
   nl;
   )

sing_bottles_of_beer 99; </lang> The output of singing with 3 bottles is:

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

No more bottles of beer on the wall
No more bottles of beer
Go to the store and buy some more
3 bottles of beer on the wall

Forth

<lang forth>:noname dup . ." bottles" ;

noname ." 1 bottle"  ;
noname ." no more bottles" ;

create bottles , , ,

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

99 verses</lang>

Fortran

<lang fortran>program bottlestest

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

end program bottlestest</lang>

Frege

Translation of: Haskell
Works with: Frege version 3.20.113

<lang frege>module Beer where

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

               ++ show v
               ++" bottles of beer\nTake one down, pass it around\n"
               ++ head (lines $ beer $ v-1) ++ "\n"

main _ = mapM_ (printStrLn . beer) (reverse (0..99))</lang>

friendly interactive shell

<lang fishshell>set i 99

  1. Assign s to variable $s

set s s while test $i != 'No more'

   echo $i bottle$s of beer on the wall,
   echo $i bottle$s of beer.
   echo Take one down, pass it around,
   set i (math $i - 1)
   if test $i -eq 1
       set s ""
   else if test $i -eq 0
       set i 'No more'
   end
   echo $i bottle$s of beer on the wall.
   if test $i != 'No more'
       echo
   end

end</lang>

Frink

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

for n = 99 to 0 step -1 {

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

}

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

Sample randomized output:

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

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

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

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

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

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

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

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

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

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

GAP

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

gnuplot

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

Go

<lang go>package main

import "fmt"

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

Go!

Copied from The 99 Bottles of Beer web site with a minor bug fix. <lang go!>-- -- 99 Bottles of Beer in Go! -- John Knottenbelt -- -- Go! is a multi-paradigm programming language that is oriented -- to the needs of programming secure, production quality, agent -- based applications. -- -- http://www.doc.ic.ac.uk/~klc/dalt03.html --

main .. {

 include "sys:go/io.gof".
 include "sys:go/stdlib.gof".
 main() ->
     drink(99);
     stdout.outLine("Time to buy some more beer...").
 drink(0) -> {}.
 drink(i) -> stdout.outLine(
      bottles(i) <> " on the wall,\n" <>
      bottles(i) <> ".\n" <>
      "take one down, pass it around,\n" <>
      bottles(i-1) <> " on the wall.\n");
     drink(i-1).
 bottles(0) => "no bottles of beer".
 bottles(1) => "1 bottle of beer".
 bottles(i) => i^0 <> " bottles of beer".

}</lang>

Gosu

<lang gosu> for (i in 99..0) {

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

} </lang>

Golfscript

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

Groovy

Basic Solution

With a closure to handle special cardinalities of bottles. <lang groovy>def bottles = { "${it==0 ? 'No more' : it} bottle${it==1 ?  : 's' }" }

99.downto(1) { i ->

   print """

${bottles(i)} of beer on the wall ${bottles(i)} of beer Take one down, pass it around ${bottles(i-1)} of beer on the wall """ }</lang>

Single Print Version

Uses a single print algorithm for all four lines. Handles cardinality on bottles, uses 'No more' instead of 0. <lang groovy>298.downto(2) {

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

}</lang>

Bottomless Beer Solution

Using more closures to create a richer lyrical experience. <lang groovy>def bottles = { "${it==0 ? 'No more' : it} bottle${it==1 ?  : 's' }" }

def initialState = {

 """${result(it)}

${resultShort(it)}""" }

def act = {

 it > 0 ?
     "Take ${it==1 ? 'it' : 'one'} down, pass it around" :
     "Go to the store, buy some more"

}

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

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

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

// //// uncomment commented lines to create endless drunken binge //// // // while (true) { 99.downto(0) { i ->

 print """

${initialState(i)} ${act(i)} ${result(i+delta(i))} """ } // Thread.sleep(1000) // }</lang>

GUISS

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

<lang guiss>Start,Programs,Accessories,Calculator,Button:9,Button:9, Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals], Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals], Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals], Button:[hyphen],Button:1,Button:[equals],Button:[hyphen],Button:1,Button:[equals] </lang> We haven't drank all of the bottles at this point, but we can keep going, if we want.

Haskell

A relatively concise solution:

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

               ++ show v 
               ++" bottles of beer\nTake one down, pass it around\n" 
               ++ head (lines $ beer $ v-1) ++ "\n"</lang>

As a list comprehension:

<lang haskell>import qualified Char

main = putStr $ concat

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

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

<lang haskell>{-# LANGUAGE TemplateHaskell #-} -- build with "ghc --make beer.hs" module Main where import Language.Haskell.TH import Control.Monad.Writer

-- This is calculated at compile time, and is equivalent to -- songString = "99 bottles of beer on the wall\n99 bottles..." songString =

   $(let
        sing = tell -- we can't sing very well...
        someBottles 1 = "1 bottle of beer "
        someBottles n = show n ++ " bottles of beer "
        bottlesOfBeer n = (someBottles n ++) 
        verse n = do
          sing $ n `bottlesOfBeer` "on the wall\n"
          sing $ n `bottlesOfBeer` "\n"
          sing $ "Take one down, pass it around\n"
          sing $ (n - 1) `bottlesOfBeer` "on the wall\n\n"
        song = execWriter $ mapM_ verse [99,98..1]
     in return $ LitE $ StringL $ song)

main = putStr songString</lang>

Haxe

<lang haxe>class RosettaDemo {

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

}</lang>

HicEst

<lang hicest>DO x = 99, 1, -1

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

ENDDO</lang>

HQ9+

<lang hq9plus>9</lang>

Icon and Unicon

The default is 99 bottles, but you can change this on the command line for really long trips... <lang icon>procedure main(args)

  numBeers := integer(args[1]) | 99
  drinkUp(numBeers)

end

procedure drinkUp(beerMax)

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

end</lang>

IDL

<lang IDL>Pro bottles

for i=1,99 do begin

print, 100-i, " bottles of beer on the wall.", 100-i, $
" bottles of beer.", " Take one down, pass it around," , $
99-i, " bottles of beer on the wall."

endfor End

</lang>

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

<lang IDL>Pro bottles_noloop

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

End</lang>

Inform 6

<lang inform6>[ Bottles i;

 if(i == 1) return "bottle";
 return "bottles";

];

[ Beer i;

 print i, " ", (string) Bottles(i), " of beer on the wall^";
 print i, " ", (string) Bottles(i), " of beer^";
 print "Take one down, pass it around^";
 i--;
 print i, " ", (string) Bottles(i), " of beer on the wall^^";
 if(i ~= 0) Beer(i);

];

[ Main;

 Beer(99);

]; </lang>

Inform 7

Programmatic solution

<lang inform7>Beer Hall is a room.

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

World model solution

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

<lang inform7>Beer Hall is a room.

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

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

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

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

Intercal

See 99 Bottles of Beer/Intercal

Io

<lang io>bottles := method(i,

   if(i==0, return "no more bottles of beer")
   if(i==1, return "1 bottle of beer")
   "" .. i .. " bottles of beer"

) for(i, 99, 1, -1,

   write(
       bottles(i), " on the wall, ", 
       bottles(i), ",\n",
       "take one down, pass it around,\n",
       bottles(i - 1), " on the wall.\n\n"
   )

)</lang>

Ioke

<lang ioke>bottle = method(i,

 case(i,
   0, "no more bottles of beer",
   1, "1 bottle of beer",
   "#{i} bottles of beer"))

(99..1) each(i,

 "#{bottle(i)} on the wall, " println
 "take one down, pass it around," println
 "#{bottle(i - 1)} on the wall.\n" println

)</lang>

J

As posted at the J wiki <lang j>bob =: ": , ' bottle' , (1 = ]) }. 's of beer'"_ bobw=: bob , ' on the wall'"_ beer=: bobw , ', ' , bob , '; take one down and pass it around, ' , bobw@<: beer"0 >:i.-99</lang>

Output: <lang j>99 bottles of beer on the wall, 99 bottles of beer; take one down and pass it around, 98 bottles of beer on the wall 98 bottles of beer on the wall, 98 bottles of beer; take one down and pass it around, 97 bottles of beer on the wall ... 3 bottles of beer on the wall, 3 bottles of beer; take one down and pass it around, 2 bottles of beer on the wall 2 bottles of beer on the wall, 2 bottles of beer; take one down and pass it around, 1 bottle of beer on the wall 1 bottle of beer on the wall, 1 bottle of beer; take one down and pass it around, 0 bottles of beer on the wall </lang>

Java

Console

MessageFormat's choice operator is used to properly format plurals. <lang java>import java.text.MessageFormat; public class Beer {

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

}</lang>

Optimized <lang java>public class Beer {

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

}</lang>

Recursive <lang java>public class Beer { public static void main(String args[]) { song(99); }

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

An object-oriented solution

Translation of: C++

See: 99 Bottles of Beer/Java/Object Oriented

GUI

Library: Swing
Library: AWT

This version requires user interaction. The first two lines are shown in a text area on a window. The third line is shown on a button which you need to click to see the fourth line in a message box. The numbers update and the process repeats until "0 bottles of beer on the wall" is shown in a message box, when the program ends. <lang java>import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextArea; public class Beer extends JFrame implements ActionListener{

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

}</lang>

JavaScript

The simple solution

<lang javascript>// Line breaks are in HTML var beer = 99; while (beer > 0) {

document.write( beer + " bottles of beer on the wall
" ); document.write( beer + " bottles of beer
" ); document.write( "Take one down, pass it around
" ); document.write( (beer - 1) + " bottles of beer on the wall
" ); beer--;

}</lang>

More skilled solution "one-liner" with grammar check

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

Object Oriented with DOM

<lang javascript>// Line breaks are in HTML function Bottles(count){

   this.count = (!!count)?count:99;
   this.knock = function(){
       var c = document.createElement('div');
       c.id="bottle-"+this.count;

c.innerHTML = "

"+this.count+" bottles of beer on the wall

" +"

"+this.count+" bottles of beer!

" +"

Take one down,
Pass it around

" +"

"+(--this.count)+" bottles of beer on the wall


";

       document.body.appendChild(c);
   }
   this.sing = function(){
       while (this.count>0) { this.knock(); }
   }

}

(function(){

   var bar = new Bottles(99);
   bar.sing();

})();</lang>

An alternative version:

<lang javascript>function bottleSong(n) {

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

}

window.onload = bottleSong;</lang>

Without DOM

<lang javascript> (function(){var beer = 99,string=; while (beer > 0) {

string+=beer+"bottles of beer on the wall\n"+ //inline line appending shouldn't be as expensive.
beer + 
"bottles of beer\nTake one down, pass it around\n"+
(--beer)+ 
" bottles of beer on the wall\n" ;

} console.log(string); })()</lang>

Joy

<lang joy>LIBRA

_beerlib == true ;

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

IN (* n -- *) sing-verses == [null] [sing-verse-0] [sing-verse 1 -] tailrec .</lang>

Julia

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

K

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

Kotlin

<lang kotlin>fun main(args : Array<String>) {

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

} </lang>

LabVIEW

This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.


Lasso

Simple loop

<lang Lasso>local(

   beer = 99,
   song = 

) while(#beer > 0) => {

   #song->append(
       #beer + ' bottles of beer on the wall\n' +
       #beer + ' bottles of beer\n' + 
       'Take one down, pass it around\n' +
       (#beer-1) + ' bottles of beer on the wall\n\n'  
   )
   #beer--

}

  1. song</lang>

Query Expression

<lang Lasso>(with beer in 99 to 1 by -1 select

   #beer + ' bottles of beer on the wall' +
   #beer + ' bottles of beer\n' + 
   'Take one down, pass it around\n' +
   --#beer + ' bottles of beer on the wall\n'

)->join('\n')</lang>


Query Expression with Autocollect

<lang Lasso>// this example adds an "s" to bottle until there is only 1 bottle left on the wall

local(s = 's') with n in 99 to 1 by -1 do {^

   #n + ' bottle' + #s + ' of beer on the wall,
' #n + ' bottle' + #s + ' of beer,
' #n = #n - 1 #s = (#n != 1 ? 's' | ) 'Take one down, pass it around,
' #n + ' bottle' + #s + ' of beer on the wall.

'

^}</lang>

LaTeX

Recursive

<lang LaTeX>\documentclass{article}

\newcounter{beer}

\newcommand{\verses}[1]{

 \setcounter{beer}{#1}
 \par\noindent
 \arabic{beer} bottles of beer on the wall,\\
 \arabic{beer} bottles of beer!\\
 Take one down, pass it around---\\
 \addtocounter{beer}{-1}
 \arabic{beer} bottles of beer on the wall!\\
 \ifnum#1>0 
   \verses{\value{beer}}
 \fi

}

\begin{document} \verses{99} \end{document}</lang>

Iterative

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

<lang LaTeX>\documentclass{article}

\newcounter{beer} \newcounter{showC}

\newcommand{\verses}[1]{

 \setcounter{beer}{#1}
 \loop
   \par\noindent
   \Roman{beer} bottles of beer on the wall,\\
   \Roman{beer} bottles of beer!\\
   Take one down, pass it around---\\
   \addtocounter{beer}{-1}

% Romans didn't know how to write zero ;-)

   \ifnum\value{beer}=0 ZERO \else\Roman{beer} \fi
     bottles of beer on the wall!\\
   \ifnum\value{beer}>0 
 \repeat

}

\begin{document} \verses{99} \end{document}</lang>

References

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

lang5

<lang lang5>: ~ 2 compress "" join ;

verses(*)
   dup " bottles of beer on the wall\n" ~ .
   dup " bottles of beer\n" ~ .
   "Take one down, pass it around\n" .
   1 - " bottles of beer on the wall\n\n" ~ .
   ;

99 iota 1 + reverse verses</lang>

Lhogho

<lang logo>to bottle :i

   if :i = 0 [output "|No more bottles of beer|]
   if :i = 1 [output "|One bottle of beer|]
   output word :i "| bottles of beer|

end

to it_one :n

   if :n = 1 [output "it][output "one]

end

to verse :i

   (print bottle :i "| on the wall,|)
   (print word bottle :i ".)
   (print "Take it_one :i "|down, pass it round|)
   (print bottle :i - 1 "| on the wall.|)
   print

end

to sing :i

   if :i = 0 
   [
   print "|No more bottles of beer on the wall,

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

   stop
   ]
   verse :i
   sing :i - 1

end

Using it

sing 99</lang>

LiveCode

<lang livecode>function beerMe numberOfBottles

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

end beerMe</lang>

Lisp

Bit of a beginner in Lisp, but this seems to work: <lang lisp>(defun beer-verse (count)

 "Recurses the verses"
 (format t "~A bottle~A of beer on the wall~%"
   count
   (if (/= count 1) "s" ""))
 (format t "~A bottle~A of beer~%"
   count
   (if (/= count 1) "s" ""))
 (format t "Take one down, pass it round~%")
 (format t "~A bottle~A of beer on the wall~%~%"
   (if (= count 1)
     "No"
     (- count 1))
   (if (/= count 2)
     "s"
     ""))
 (if (> count 1)
   (beer-verse (- count 1))))

(beer-verse 99) </lang> Output (last three verses only):

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

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

1 bottle of beer on the wall
1 bottle of beer
Take one down, pass it round
No bottles of beer on the wall

LLVM

<lang llvm>; "99 Bottles of Beer on the Wall" in LLVM Assembly

This is not strictly LLVM, as it uses the C library function "printf".
LLVM does not provide a way to print values, so the alternative would be
to just load the string into memory, and that would be boring.
The song lyrics are global constants.
Lyrics for plural verses

@pluralVerse = private constant [120 x i8] c"%d bottles of beer on the wall, %d bottles of beer.\0ATake one down and pass it around, %d bottles of beer on the wall.\0A\0A\00"

Lyrics for the singular verse

@singularVerse = private constant [121 x i8]

   c"1 bottle of beer on the wall, 1 bottle of beer.\0ATake one down and pass it around, no more bottles of beer on the wall.\0A\0A\00"
Lyrics for the final verse

@finalVerse = private constant [130 x i8]

   c"No more bottles of beer on the wall, no more bottles of beer.\0AGo to the store and buy some more, %d bottles of beer on the wall.\0A\00"
Initial number of bottles of beer.
This must be a natural number.

@initialVerseNumber = private constant i32 99

The declaration for the external C printf function.

declare i32 @printf(i8*, ...)

Prints a verse, with %numberOfBottles being the initial number of bottles
in that verse.

define fastcc void @printVerse(i32 %numberOfBottles) {

   switch i32 %numberOfBottles, 
       label %pluralVerse
       [ i32 1, label %singularVerse
         i32 0, label %finalVerse ]

pluralVerse:

   %pluralVersePointer = getelementptr [120 x i8]* @pluralVerse, i64 0, i64 0
   %newNumberOfBottles = sub i32 %numberOfBottles, 1
   call i32(i8*, ...)* @printf(
       i8* %pluralVersePointer,
       i32 %numberOfBottles,
       i32 %numberOfBottles,
       i32 %newNumberOfBottles)
   ret void

singularVerse:

   %singularVersePointer = getelementptr [121 x i8]* @singularVerse,i64 0,i64 0
   call i32(i8*, ...)* @printf(i8* %singularVersePointer)
   ret void

finalVerse:

   %finalVersePointer = getelementptr [130 x i8]* @finalVerse, i64 0, i64 0
   %initialVerseNumberL = load i32* @initialVerseNumber
   call i32(i8*, ...)* @printf(i8* %finalVersePointer,i32 %initialVerseNumberL)
   ret void

}

define i32 @main() { loopHeader:

   %initialVerseNumberL = load i32* @initialVerseNumber
   br label %loop ; This br terminates the first basic block.

loop:

   %verseNumber = 
       phi i32 [%initialVerseNumberL, %loopHeader], [%nextVerseNumber, %do]
   %cond = icmp eq i32 -1, %verseNumber
   br i1 %cond, label %break, label %do

do:

   call fastcc void @printVerse(i32 %verseNumber)
   %nextVerseNumber = sub i32 %verseNumber, 1
   br label %loop

break:

   ret i32 0

}</lang>

<lang logo>to bottles :n

 if :n = 0 [output [No more bottles]]
 if :n = 1 [output [1 bottle]]
 output sentence :n "bottles

end to verse :n

 print sentence bottles :n [of beer on the wall]
 print sentence bottles :n [of beer]
 print [Take one down, pass it around]
 print sentence bottles :n-1 [of beer on the wall]

end for [n 99 1] [verse :n (print)]</lang>

Logtalk

<lang logtalk>:- object(bottles).

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

LOLCODE

<lang LOLCODE>HAI 1.3

I HAS A bottles ITZ 99 I HAS A plural ITZ "Z" I HAS A lyric ITZ "99 BOTTLZ OV BEER"

IM IN YR song

   VISIBLE lyric " ON TEH WALL"
   VISIBLE lyric
   VISIBLE "TAEK 1 DOWN, PAZ IT AROUN"
   bottles R DIFF OF bottles AN 1
   NOT bottles, O RLY?
       YA RLY, VISIBLE "NO MOAR BOTTLZ OV BEER ON TEH WALL", GTFO
   OIC
   BOTH SAEM bottles AN 1, O RLY?
       YA RLY, plural R ""
   OIC
   lyric R SMOOSH bottles " BOTTL" plural " OV BEER" MKAY
   VISIBLE lyric " ON TEH WALL:)"

IM OUTTA YR song

KTHXBYE</lang>

Lua

<lang lua>local bottles = 99

local function plural (bottles) if bottles == 1 then return end return 's' end while bottles > 0 do

   print (bottles..' bottle'..plural(bottles)..' of beer on the wall')
   print (bottles..' bottle'..plural(bottles)..' of beer')
   print ('Take one down, pass it around')
   bottles = bottles - 1
   print (bottles..' bottle'..plural(bottles)..' of beer on the wall')
   print ()

end</lang>

Lucid

<lang lucid>// Run luval with -s inside the lucid shell script // The print out is a list of lines. So the output is not separated by new lines, rather // by '[' and ']' -- I cant figure out how to do string concatenation with numbers in lucid. // beer(N) ^ bottle(N) ^ wall ^ beer(N) ^ bottle(N) ^ pass ^ beer(N-1) ^ bottle(N-1) ^ wall // should have worked but doesn't [%beer(N),bottle(N),wall,beer(N),bottle(N),pass,beer(N-1),bottle(N-1),wall%]

  where
      N = 100 fby N - 1;
      wall = if N > 0 then ` On the wall ' else eod fi;
      pass = `Take one down and pass it around.';
      beer(A) = if A > 0 then A else `No more' fi;
      bottle(A) = if A eq 1 then `bottle of beer' else `bottles of beer' fi;
  end</lang>

M4

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

make

BSD make

Library: jot
Works with: BSD make

<lang make>START = 99 UP != jot - 2 `expr $(START) - 1` 1

0-bottles-of-beer: 1-bottle-of-beer @echo No more bottles of beer on the wall!

1-bottle-of-beer: 2-bottles-of-beer @echo One last bottle of beer on the wall! @echo @echo One last bottle of beer on the wall, @echo One last bottle of beer, @echo Take it down, pass it around.

.for COUNT in $(UP) ONE_MORE != expr 1 + $(COUNT) $(COUNT)-bottles-of-beer: $(ONE_MORE)-bottles-of-beer @echo $(COUNT) bottles of beer on the wall! @echo @echo $(COUNT) bottles of beer on the wall, @echo $(COUNT) bottles of beer, @echo Take one down, pass it around. .endfor

$(START)-bottles-of-beer: @echo $(START) bottles of beer on the wall, @echo $(START) bottles of beer. @echo Take one down, pass it around.</lang>

Usage: make or make START=99

GNU make

Works with: GNU make version 3.81

<lang make>PRED=`expr $* - 1`

1-bottles: 1-beer pass @echo "No more bottles of beer on the wall"

%-bottles: %-beer pass @echo "$(PRED) bottles of beer on the wall\n" @-$(MAKE) $(PRED)-bottles

1-beer: @echo "One bottle of beer on the wall, One bottle of beer"

%-beer: @echo "$* bottles of beer on the wall, $* bottles of beer"

pass: @echo "Take one down and pass it around,"</lang>

Usage: make 99-bottles

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

Mathematica

<lang Mathematica>Bottle[n_] := ToString[n] <> If[n==1," bottle"," bottles"] <> " of beer"

BottleSong[n_] := Speak[

 Bottle[n] <> " on the wall," <>
 Bottle[n] <>
 ", take one down, pass it around," <>
 Bottle[n-1] <> " on the wall."

]

BottleSong /@ Range[99,1,-1]</lang>

MATLAB

<lang MATLAB>function ninetyNineBottlesOfBeer()

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

end</lang>

Maxima

<lang maxima>bottle(n) := if n = 1 then "bottle" else "bottles"$

bottles(n) := block(

  for i from n thru 1 step -1 do (
     printf(true, "~d ~a of beer on the wall~%", i, bottle(i)),
     printf(true, "~d ~a of beer~%", i, bottle(i)),
     printf(true, "Take one down, pass it around~%"),
     printf(true, "~d ~a of beer on the wall~%", i - 1, bottle(i - 1)),
     disp("")
  )

)$

bottles(99);</lang>

MAXScript

<lang maxscript>escapeEnable = true resetMaxFile #noPrompt viewport.setType #view_top max tool maximize viewport.SetRenderLevel #smoothhighlights delay = 1.6 a = text size:30 a.wirecolor = white theMod = extrude() addModifier a theMod

for i in 99 to 1 by -1 do -- this will iterate through 99 times use the escape key to terminate. (

   a.text = (i as string + " bottles of beer on the wall")
   redrawViews()
   sleep delay 
   a.text = (i as string + " bottles of beer")
   redrawViews()
   sleep delay 
   a.text = "Take one down, pass it around"
   redrawViews()
   sleep delay 
   a.text = ((i-1) as string + " bottles of beer on the wall")
   redrawViews()
   sleep delay 

)</lang>

A one-line version

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

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

Mirah

<lang Mirah>plural = 's' 99.downto(1) do |i|

 puts "#{i} bottle#{plural} of beer on the wall,"
 puts "#{i} bottle#{plural} of beer"
 puts "Take one down, pass it around!"
 plural =  if i - 1 == 1
 if i > 1
   puts "#{i-1} bottle#{plural} of beer on the wall!"
   puts
 else
   puts "No more bottles of beer on the wall!"
 end

end </lang>

mIRC Scripting Language

<lang mirc>var %x = 99 while (%x) {

 echo -ag %x bottles of beer on the wall
 echo -ag %x bottles of beer
 echo -ag Take one down, pass it around
 dec %x
 echo -ag %x bottles of beer on the wall

}</lang>

ML/I

Simple iterative version

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

MCGO L1 > "" Do it BOTTLES 99</lang>

Recursive version

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

BOTTLES %T1. > "" Do it BOTTLES 99</lang>


Macro Processing generalized version in 99 lines

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

The code defines a macro

Sing n containers of contents somewhere : deed ! replenish .

where the text (macro call)

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

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

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

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

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

<lang ML/I> MCSKIP - WITH - NL -- The line above defines the comment syntax: -- through to newline is completely deleted. -- 99 Bottles of beer in 99 lines of ML/I by Parzival Herzog. -- ML/I is P.J. Brown's famous general purpose macro processor designed in 1967. -- -- Define nestable quotes {...}, replaced by the unevaluated text within: MCSKIP MT, {} -- Define non-nestable quotes "...", replaced by the unevaluated text within: MCSKIP T, "" -- Define the argument insertion and expression evaluation syntax: -- ?e. is replaced by the value of macro expression e: MCINS ?. -- -- Top level macro: Sing N CONTAINERS of CONTENTS SOMEWHERE : DO THE DEED! REPLENISH. MCDEF "Sing WITH SPACE SPACE of WITH SPACE SPACE  :  ! ." AS -- {MCDEF "CONTAINERS" AS "{"?A2."}" MCDEF "CONTAINER" AS "{"MCSUB(CONTAINERS,1,-1)"}" MCDEF "CONTENTS" AS "{"?A3."}" MCDEF "SOMEWHERE" AS "{"?A4."}" MCDEF "DO WITHS THE WITHS DEED" AS "{"?A5."}" MCDEF "REPLENISH" AS "{"?A6."}" MCSET T1 = ?A1. MCDEF "n" AS "("?T1.")" MCDEF "N" AS "{"n"}" ?L1.n of CONTENTS SOMEWHERE,

   n of CONTENTS.

MCGO L2 UNLESS ?T1. GR 0 MCSET T1 = T1 - 1 MCDEF "n" AS "("?T1.")" DO THE DEED:

   n of CONTENTS SOMEWHERE.

MCGO L1 ?L2.REPLENISH:

   N of CONTENTS SOMEWHERE!}

-- -- (n): Wordify 0 to 99 CONTAINERS MCDEF "()" AS {MCSET T1=?A1. MCGO L1 UNLESS T1 GR 99 ?T1. CONTAINERS-- Return the decimal number instead of words. MCGO L0 ?L1.MCGO L2 IF T1 GR 9 MCDEF "0units" AS ?T1."Unit" MCGO L3 ?L2.MCSET T3 = T1 - T1/10*10 MCDEF "0units" AS ?T3."unit" MCSET T1 = T1 / 10 MCDEF "0tens" AS ?T1."Ten" 0tens?L3.0units CONTAINERS} -- Exceptions: MCDEF "(WITH 0 WITH)" AS {"No more" CONTAINERS} MCDEF "(WITH 1 WITH)" AS {"One more" CONTAINER} MCDEF "(WITH 11 WITH)" AS {"Eleven" CONTAINERS} MCDEF "(WITH 12 WITH)" AS {"Twelve" CONTAINERS} MCDEF "(WITH 13 WITH)" AS {"Thirteen" CONTAINERS} MCDEF "(WITH 14 WITH)" AS {"Fourteen" CONTAINERS} MCDEF "(WITH 15 WITH)" AS {"Fifteen" CONTAINERS} MCDEF "(WITH 16 WITH)" AS {"Sixteen" CONTAINERS} MCDEF "(WITH 17 WITH)" AS {"Seventeen" CONTAINERS} MCDEF "(WITH 18 WITH)" AS {"Eighteen" CONTAINERS} MCDEF "(WITH 19 WITH)" AS {"Nineteen" CONTAINERS} -- Regular cases: MCDEF "2Unit" AS {"Two"} MCDEF "3Unit" AS {"Three"} MCDEF "4Unit" AS {"Four"} MCDEF "5Unit" AS {"Five"} MCDEF "6Unit" AS {"Six"} MCDEF "7Unit" AS {"Seven"} MCDEF "8Unit" AS {"Eight"} MCDEF "9Unit" AS {"Nine"} MCDEF "0unit" AS MCDEF "1unit" AS {" one"} MCDEF "2unit" AS {" two"} MCDEF "3unit" AS {" three"} MCDEF "4unit" AS {" four"} MCDEF "5unit" AS {" five"} MCDEF "6unit" AS {" six"} MCDEF "7unit" AS {" seven"} MCDEF "8unit" AS {" eight"} MCDEF "9unit" AS {" nine"} MCDEF "1Ten" AS {"Ten"} MCDEF "2Ten" AS {"Twenty"} MCDEF "3Ten" AS {"Thirty"} MCDEF "4Ten" AS {"Forty"} MCDEF "5Ten" AS {"Fifty"} MCDEF "6Ten" AS {"Sixty"} MCDEF "7Ten" AS {"Seventy"} MCDEF "8Ten" AS {"Eighty"} MCDEF "9Ten" AS {"Ninety"} -- -- The specified song: Sing 99 bottles of beer on the wall: Take one down, pass it around! -- Go to the store and buy some more. -- -- -- Try uncommenting the next two lines: -- Sing 7 flasks of Armagnac on the table: Take a swig, throw it down! -- Emilie vists, she brings some more. </lang>

Usage:

ml1 "Bottles of Beer.ml1"


Output:

<lang ML/I> Ninety nine bottles of beer on the wall,

   Ninety nine bottles of beer.

Take one down, pass it around:

   Ninety eight bottles of beer on the wall.

Ninety eight bottles of beer on the wall,

   Ninety eight bottles of beer.

Take one down, pass it around:

   Ninety seven bottles of beer on the wall.
   ...


One more bottle of beer on the wall,

   One more bottle of beer.

Take one down, pass it around:

   No more bottles of beer on the wall.

No more bottles of beer on the wall,

   No more bottles of beer.

Go to the store and buy some more:

   Ninety nine bottles of beer on the wall!

</lang>

Modula-2

<lang modula2>MODULE b99; IMPORT InOut;

VAR nr  : CARDINAL;

BEGIN

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

END b99.</lang>

Modula-3

<lang modula3>MODULE Bottles EXPORTS Main;

IMPORT IO, Fmt;

BEGIN

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

END Bottles.</lang>

Monkey

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

Import mojo

Function Main () New NintyNineBottles End


Class NintyNineBottles Extends App

Field _bottles:Int = 99 Field _y:Int=640 Field tic:Int Field duration:Int = 1500 Field lyric:Int = 1 Method OnCreate () SetUpdateRate 60 End

' Stuff to do while running... Method OnUpdate () If Millisecs()-Self.tic > Self.duration Self.tic=Millisecs() If Self.lyric= 4 Then Self._bottles-=1 Self.lyric+=1


End If End

' Drawing code...

Method OnRender () Cls

Select Self.lyric Case 1 DrawText(_bottles+" bottles of beer on the wall",10,10) Case 2 DrawText(_bottles+" bottles of beer",10,10) Case 3 If Self._bottles > 1 DrawText("take one down",10,10) Else DrawText("take it down",10,10) End If Case 4 DrawText("Pass it around",10,10) Case 5 If Self._bottles>0 DrawText(Self._bottles+" bottles of beer on the wall",10,10) Else DrawText("no more bottles of beer on the wall",10,10) End If Case 6 If Self._bottles>0 Self.lyric=1'DrawText(Self._bottles+" bottles of beer on the wall",10,10) Else DrawText("no more bottles of beer",10,10) End if Case 7 DrawText("go to the store",10,10)

Case 8 DrawText("and buy some more",10,10) Case 9 Self._bottles=99 DrawText(_bottles+" more bottles of beer on the wall",10,10) Case 10 Self.lyric=1 End Select

End


End


</lang>

MOO

<lang moo>bottles = 99; while (bottles > 0)

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

endwhile player:tell("0 bottles of beer on the wall.");</lang>

MPIF90

<lang fortran>program bottlesMPI

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

end program bottlesMPI</lang>

Usage

 mpif90 filename.f90
 mpiexec -np 99 a.out

MUMPS

Recursive

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

Do beer(99)</lang>

Iterative

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

For ii=99:-1:0 Do beer(ii)</lang>

NASL

<lang nasl>bottles = 99; repeat {

 display(bottles, ' bottles of beer on the wall\n');
 display(bottles, ' bottles of beer\n');
 display('Take one down, pass it around\n');
 display(--bottles, ' bottles of beer on the wall\n\n');

} until bottles < 1;</lang>

Nemerle

<lang Nemerle>using System; using System.Console;

module Bottles {

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

}</lang>

NetRexx

<lang netrexx> beer = "bottles of beer on the wall" removeOne = "Take one down, pass it arround," say 99 beer"," say 99 beer.subword(1,3)"," loop i = 98 to 2 by -1

 say removeOne
 say i beer"."
 say
 say i beer","
 say i beer.subword(1,3)","

end lastCall = "bottle" beer.delword(1,1) say removeOne say i lastCall"." say say i lastCall"," say i lastCall.subword(1,3)"," say removeOne say "No more" beer </lang>

NewLISP

<lang newlisp>(for (n 99 1) (println n " bottles of beer on the wall," n " bottles of beer. Take one down, pass it around. ") (println (- n 1) "bottles of beer on the wall!"))

recursive
also shows list afterword

(define (rec bottles) (if (!= 0 bottles) (print "/n" bottles " bottles of beer on the wall" bottles " bottles of beer. \nTake one down, pass it around, " (- bottles 1) " bottles of beer on the wall" (rec ( - bottles 1))))(list bottles))

(rec 99)</lang>

Nial

<lang nial>line is fork [

 0=, 'No more bottles of beer' first,
 1=, 'One bottle of beer' first, 
 link [string,' bottles of beer' first]

]

verse is link [

 line, ' on the wall, ' first,line,
 '. Take it down and pass it around, ' first,
 line (-1+),'on the wall. ' first

]

bottles is iterate (write verse) reverse count</lang>

Nimrod

<lang nimrod>proc GetBottleNumber(n: int): string =

 var bs: string
 if n == 0:
   bs = "No more bottles"
 elif n == 1:
   bs = "1 bottle"
 else:
   bs = $n & " bottles"
 return bs & " of beer"

for bn in countdown(99, 1):

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

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

Objective-C

<lang objc>#import <Foundation/Foundation.h>

int main() {

   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   int bottles = 99;
   do
   {
       NSLog(@"%i bottles of beer on the wall\n", bottles);
       NSLog(@"%i bottles of beer\n", bottles);
       NSLog(@"Take one down, pass it around\n");
       NSLog(@"%i bottles of beer on the wall\n\n", --bottles);
   } while (bottles > 0);
   [pool drain];
   return 0;

}</lang>

Oberon-2

<lang oberon2>MODULE b99;

IMPORT Out;

VAR nr  : INTEGER;

BEGIN

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

END b99.</lang>

OCaml

<lang ocaml>for n = 99 downto 1 do

 Printf.printf "%d bottles of beer on the wall\n" n;
 Printf.printf "%d bottles of beer\n" n;
 Printf.printf "Take one down, pass it around\n";
 Printf.printf "%d bottles of beer on the wall\n\n" (pred n);

done</lang>

Recursive version that handles plurals.

<lang ocaml>let verse n =

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

let rec beer n =

   print_endline (verse n);
   if n > 1 then beer (n-1);;

beer 99;;</lang>

Octave

<lang octave>function bottles(n)

 bottle = "bottle";
 ofbeer = "of beer";
 wall = "on the wall";
 for i = n:-1:0
   if ( i == 1 )
     s = "";
   else
     s = "s";
   endif
   for j = 0:1
     w = wall;
     if ( j == 1 )

w = "";

     endif
     printf("%d %s%s %s %s\n",\

i, bottle, s, ofbeer, w);

   endfor
   printf("Take one down, pass it around\n");
 endfor

endfunction

bottles(99);</lang>

ooRexx

The rexx example below runs unchanged on ooRexx

OpenEdge/Progress

<lang Progress (Openedge ABL)>DEFINE VARIABLE amountofbottles AS INTEGER NO-UNDO INITIAL 99. &GLOBAL-DEFINE bbm bottles of beer &GLOBAL-DEFINE bbs bottle of beer &GLOBAL-DEFINE otw on the wall &GLOBAL-DEFINE tow Take one down and pass it around, &GLOBAL-DEFINE gts Go to the store and buy some more, FUNCTION drinkBottle RETURNS INTEGER PRIVATE (INPUT bc AS INTEGER) FORWARD.

OUTPUT TO OUTPUT.txt. drinkBottle(amountofbottles). OUTPUT CLOSE.

FUNCTION drinkBottle RETURNS INTEGER.

   IF bc >= 0 THEN DO:
       CASE bc:
       WHEN 2 THEN
           PUT UNFORMATTED bc " {&bbm} {&otw}, " bc " {&bbm}" SKIP 
                           "{&tow} " bc - 1 " {&bbs} {&otw}" SKIP.
       WHEN 1 THEN
           PUT UNFORMATTED bc " {&bbs} {&otw}, " bc " {&bbs}" SKIP 
                           "{&tow} no more {&bbm} {&otw}" SKIP.
       WHEN 0 THEN
           PUT UNFORMATTED "no more" " {&bbm} {&otw}, no more {&bbm}" SKIP 
                           "{&gts} " amountofbottles " {&bbm} {&otw}" SKIP.
       OTHERWISE
           PUT UNFORMATTED bc " {&bbm} {&otw}, " bc " {&bbm}" SKIP 
                           "{&tow} " bc - 1 " {&bbm} {&otw}" SKIP.
       END CASE.        
       drinkBottle(bc - 1).
       RETURN bc.
   END.
   RETURN 0. 

END FUNCTION.</lang>

Order

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

"Pure" Order

This solution uses only Order language constructs to generate and manipulate tokens: <lang c>#include "order/interpreter.h"

ORDER_PP (8let((8B, 8fn(8N,

              8cond((8greater(8N, 1),
                     8separate(8N, 8quote(bottles)))
                    (8equal(8N, 1),
                     8quote(1 bottle))
                    (8else,
                     8quote(no more bottles))))),
     8for_each_in_range
     (8fn(8N,
          8print(8ap(8B, 8N) (of beer on the wall,) 8space
                 8ap(8B, 8N) (of beer,) 8space
                 (take one down, pass it around,) 8space
                 8ap(8B, 8dec(8N)) (of beer on the wall.))),
      100, 1)))</lang>

C Preprocessor

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

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

ORDER_PP_FN(8fn(8N, \

               8cond((8greater(8N, 1),                \
                      8separate(8N, 8quote(bottles))) \
                     (8equal(8N, 1),                  \
                      8quote(1 bottle))               \
                     (8else,                          \
                      8quote(no more bottles)))))

ORDER_PP(8for_each_in_range

        (8fn(8N,
             8emit(8quote(GEN_phrase),
                   8tuple(8bottles(8N),
                          8bottles(8dec(8N))))),
         100, 1))
  1. undef GEN_phrase</lang>

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

Oxygene

<lang oxygene> namespace ConsoleApplication2;

interface

type

 ConsoleApp = class
 public
   class method Main(args: array of String);
 end;

implementation

method bottles(number: Integer): String; begin

   if (number = 1) then 
       Result := "bottle"
   else
       Result := "bottles";

end;

class method ConsoleApp.Main(args: array of String); begin

 for n: Integer := 99 downto 1 do
 begin
     Console.WriteLine("{0} {1} of beer on the wall,",n,bottles(n));
     Console.WriteLine("{0} {1} of beer,",n,bottles(n));
     Console.WriteLine("Take one down, and pass it around,");
     Console.WriteLine("{0} {1} of beer on the wall.",n-1,bottles(n-1));
     Console.WriteLine();
 end;
 Console.ReadKey();

end;

end. </lang>


Oz

Constraint Programming

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

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

in

 %% show all solutions to the 'puzzle'
 {ForAll {SearchAll BeerDescription}
  System.showInfo}</lang>

Iterative

<lang oz>declare

 fun {Bottles N}
    if N == 1 then "1 bottle"
    else N#" bottles"
    end
 end

in

 for I in 99..1;~1 do
    {System.showInfo
     {Bottles I}#" of beer on the wall\n"#
     {Bottles I}#" bottles of beer\n"#
     "Take one down, pass it around\n"#
     {Bottles I-1}#" of beer on the wall\n"}
 end</lang>

PARI/GP

<lang parigp>forstep(n=99,3,-1,

 print(n" bottles of beer on the wall");
 print(n" bottles of beer");
 print("Take one down, pass it around");
 print(n-1," bottles of beer on the wall\n")

); print("2 bottles of beer on the wall\n2 bottles of beer\nTake one down, pass it around\n1 bottle of beer on the wall\n"); print("1 bottle of beer on the wall\n1 bottle of beer\nTake one down, pass it around\nNo more bottles of beer on the wall")</lang>

Pascal

<lang pascal>procedure BottlesOfBeer; var

 i: Integer;

begin

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

end;</lang>

Perl

<lang perl>#!/usr/bin/perl -w

my $verse = <<"VERSE"; 100 bottles of beer on the wall, 100 bottles of beer! Take one down, pass it around! 99 bottles of beer on the wall!

VERSE

{

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

}</lang>

Alternatively: <lang perl>for $n (reverse(0..99)) {

   $bottles = sprintf("%s bottle%s of beer on the wall\n",(($n==0)?"No":$n), (($n==1)?"":"s"));
   print( (($n==99)?"":"$bottles\n") . 

(($n==0)?"":(substr(${bottles}x2,0,-12) . "\nTake one down, pass it around\n")) ); }</lang>

Correct grammar and nice spacing in modern perl: <lang perl>use 5.10.0;

$num = 99; while ($num > 0) {

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

}

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

Using perl5 as a DSL factory leveraging $_'s global nature: <lang perl>

  1. !/usr/bin/env perl

use strict; use warnings;

sub bottles() { sprintf qq{%s bottle%s of beer}

              , $_ || 'No'
              , $_==1 ?  : 's';
              }

sub store() { $_=99; qq{Go to the store, buy some more...\n}; } sub wall() { qq{ on the wall\n} } sub take() { $_-- ? qq{Take one down, pass it around\n} : store } do { print bottles, wall

        , bottles, qq{\n}
        , take
        , bottles, qq{\n\n}
  } for reverse 0..99;</lang>

Perl 6

A Simple Way

<lang perl6>my $b = 99;

sub b($b) {

   "$b bottle{'s'.substr($b == 1)} of beer";

}

repeat while --$b {

   .say for "&b($b) on the wall",
            b($b),
            'Take one down, pass it around',
            "&b($b-1) on the wall",
            ;

} </lang>

A Clearer Way

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

<lang perl6>

  1. = Sings a verse about a certian number of beers, possibly on a wall.

sub sing(

   Int $number, #= Number of bottles of beer.
   Bool $has_wall = False #= Mention that the beers are on a wall?

) {

   my $quantity = $number == 0 ?? "No more" !! $number;
   my $plural = $number == 1 ?? "" !! "s";
   my $wall = $has_wall ?? " on the wall" !! "";
   return "{$quantity} bottle{$plural} of beer{$wall}"

}

for 99...1 -> $bottles {

   .say for
       sing($bottles, True),
       sing($bottles),
       "Take one down, pass it around",
       sing($bottles-1, True),
       "";

} </lang>

A More Extravagant Way

Works with: Rakudo version #22 "Thousand Oaks"

<lang perl6>my @quantities = (99 ... 1), 'No more', 99; my @bottles = 'bottles' xx 98, 'bottle', 'bottles' xx 2; my @actions = 'Take one down, pass it around' xx 99,

             'Go to the store, buy some more';

for @quantities Z @bottles Z @actions Z

   @quantities[1 .. *] Z @bottles[1 .. *]
   -> $a, $b, $c, $d, $e {
   say "$a $b of beer on the wall";
   say "$a $b of beer";
   say $c;
   say "$d $e of beer on the wall\n";

}</lang>

PHL

Translation of: C

<lang phl>module bottles; extern printf;

@Integer main [

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

]</lang>

PHP

<lang php><?php $plural = 's'; foreach (range(99, 1) as $i) {

   echo "$i bottle$plural of beer on the wall,\n";
   echo "$i bottle$plural of beer!\n";
   echo "Take one down, pass it around!\n";
   if ($i - 1 == 1)
       $plural = ;
   
   if ($i > 1)
       echo ($i - 1) . " bottle$plural of beer on the wall!\n\n";
   else
       echo "No more bottles of beer on the wall!\n";

} ?></lang>

shorter way

<lang php><?php foreach(range(99,1) as $i) {

   $p = ($i>1)?"s":"";
   echo <<< EOV

$i bottle$p of beer on the wall $i bottle$p of beer Take one down, pass it around


EOV; } echo "No more Bottles of beer on the wall"; ?></lang>

modifing way:

<lang php><?php $verse = <<<VERSE 100 bottles of beer on the wall, 100 bottles of beer! Take one down, pass it around! 99 bottles of beer on the wall!


VERSE;

foreach (range(1,99) as $i) { // loop 99 times

   $verse = preg_replace('/\d+/e', '$0 - 1', $verse);
   $verse = preg_replace('/\b1 bottles/', '1 bottle', $verse);
   $verse = preg_replace('/\b0 bottle/', 'No bottles', $verse);
   echo $verse;

} ?></lang>

ultra compact alternative

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

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

gettext alternative

supports grammar and translations.

<lang php><?php

$bottles = 99;

while ($bottles > 0) { printf(ngettext('%d bottle', '%d bottles', $bottles) . " of beer on the wall\n", $bottles); //X bottles of beer on the wall printf(ngettext('%d bottle', '%d bottles', $bottles) . " of beer\n", $bottles); //X bottles of beer printf("Take one down, pass it around\n"); //Take one down, pass it around

$bottles--;

if ($bottles > 0) { printf(ngettext('%d bottle', '%d bottles', $bottles) . " of beer on the wall\n\n", $bottles); //X bottles of beer on the wall } } printf('No more bottles of beer on the wall'); //No more bottles of beer on the wall</lang>

PicoLisp

<lang PicoLisp>(de bottles (N)

  (case N
     (0 "No more beer")
     (1 "One bottle of beer")
     (T (cons N " bottles of beer")) ) )

(for (N 99 (gt0 N))

  (prinl (bottles N) " on the wall,")
  (prinl (bottles N) ".")
  (prinl "Take one down, pass it around,")
  (prinl (bottles (dec 'N)) " on the wall.")
  (prinl) )</lang>

Piet

see image

Pike

<lang pike>int main(){

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

}</lang>

alternate version: <lang Pike>// disclaimer: i prefer gingerale

void main() {

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

}</lang>

PIR

Works with: Parrot version Tested with 2.4.0

<lang pir>.sub sounding_smart_is_hard_after_drinking_this_many

 .param int b
 if b == 1 goto ONE
 .return(" bottles ")

ONE:

 .return(" bottle ")
 end

.end

.sub main :main

 .local int bottles
 .local string b
 bottles = 99

LUSH:

 if bottles == 0 goto DRUNK
 b = sounding_smart_is_hard_after_drinking_this_many( bottles )
 print bottles
 print b
 print "of beer on the wall\n"
 print bottles
 print b
 print "of beer\nTake one down, pass it around\n"
 dec bottles
 b = sounding_smart_is_hard_after_drinking_this_many( bottles )
 print bottles
 print b
 print "of beer on the wall\n\n"
 goto LUSH

DRUNK:

 end

.end</lang>

Plain TeX

<lang tex>\def\ifbeer{\ifnum\number\bottles} \def\beers{ \par\ifbeer>0 \the\bottles~\else No more \fi bottle\ifbeer=1\else s\fi~of beer% }

\def\take #1 down,{ \par\advance\bottles by -#1 Take #1 down, pass it around,\par }

\long\def\verse{ \beers~on the wall, \beers. \take 1 down, % curious TeX \def syntax \beers~on the wall. \bigskip }

\newcount\bottles\bottles99 \loop\verse \ifnum\number\bottles>0\repeat

\bye</lang>

Pop11

<lang pop11>define bootles(n);

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

enddefine;

bootles(99);</lang>

PostScript

<lang PostScript>%!PS /Helvetica findfont 9 scalefont setfont

/printBeer {

   dup
   20 string cvs show
   ( bottle) show
   1 ne
   { (s) show } if 
   ( of beer) show

} def

/printVerse {

   dup
   dup
   dup
   7 mul
   50 add 
   /yPos exch def
   15 yPos moveto
   printBeer
   ( on the wall, ) show
   printBeer
   (. ) show 
   (Take one down, pass it around, ) show
   1 sub
   printBeer
   ( on the wall. ) show

} def

/song {

   100 -1 1 { printVerse } for

} def

song showpage %%EOF</lang>

PowerShell

A standard impementation using a For loop

<lang PowerShell>for($n=99; $n -gt 0; $n--) {

  "$n bottles of beer on the wall"
  "$n bottles of beer"
  "Take one down, pass it around"
  [string]($n-1) + " bottles of beer on the wall"
  ""

}</lang>


My standard implementation using for loop

<lang PowerShell>[int]$i = 99; for($i=99; $i -gt 0; $i--) {

   write-host $i  " bottles of beer on the wall";
   write-host $i  " bottles of beer";
   write-host "Take one down, pass it around"
   write-host ($i-1) " bottles of beer on the wall"
   write-host ""

} </lang>

Consolidating the static text and using a Do...while loop

<lang PowerShell>$n=99 do {

  "{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n" -f $n, --$n

} while ($n -gt 0)</lang>

Consolidating the static text and using a Do...until loop

<lang PowerShell>$n=99 do {

  "{0} bottles of beer on the wall`n{0} bottles of beer`nTake one down, pass it around`n{1} bottles of beer on the wall`n" -f $n, --$n

} until ($n -eq 0)</lang>


Consolidating the static text even more

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

Using the Pipeline

<lang Powershell>99..1 | ForEach-Object {

   $s=$( if( $_ -ne 1 ) { 's' } else {  } )
   $s2=$( if( $_ -ne 2 ) { 's' } else {  } )
   "$_ bottle$s of beer on the wall`n$_ bottle$s of beer`nTake one down`npass it around`n$( $_ - 1 ) bottle$s2 of beer on the wall`n"}</lang>

ProDOS

<lang ProDOS>editvar /newvar /value=a=99

a

printline -a- bottles of beer on the wall printline -a- bottles of beer printline Take one down, pass it round editvar /newvar /value=a=-a-1 if -a- /hasvalue 1 goto :1 printline -a- bottles of beer on the wall. goto :a

1

printline 1 bottle of beer on the wall printline 1 bottle of beer printline take it down, pass it round printline no bottles of beer on the wall. editvar /newvar /value=b /userinput=1 /title=Keep drinking? if -b- /hasvalue yes goto :a else exitprogram</lang>

Prolog

Works with: SWI Prolog

<lang prolog>bottles(0):-!. bottles(X):-

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

An other version that handles plural/not plural conditions.

<lang prolog>line1(X):- line2(X),write(' on the wall'). line2(0):- write('no more bottles of beer'). line2(1):- write('1 bottle of beer'). line2(X):- writef('%t bottles of beer',[X]). line3(1):- write('Take it down, pass it around'). line3(X):- write('Take one down, pass it around'). line4(X):- line1(X).

bottles(0):-!. bottles(X):-

   succ(XN,X),
   line1(X),nl,
   line2(X),nl,
   line3(X),nl,
   line4(XN),nl,nl,
   !,
   bottles(XN).

- bottles(99).</lang>

Python

Normal Code

<lang python>def plural(word, amount): # Correctly pluralize a word.

   if amount == 1:
       return word
   else:
       return word + 's'

def sing(b, end): # Sing a phrase of the song, for b bottles, ending in end

   print b or 'No more', plural('bottle', b), end

for i in range(99, 0, -1):

   sing(i, 'of beer on the wall,')
   sing(i, 'of beer,')
   print 'Take one down, pass it around,'
   sing(i-1, 'of beer on the wall.\n')</lang>

Using a template

<lang python>verse = \ %i bottles of beer on the wall %i bottles of beer Take one down, pass it around %i bottles of beer on the wall

for bottles in range(99,0,-1):

   print verse % (bottles, bottles, bottles-1) </lang>

New-style template (Python 2.6)

<lang python>verse = \ {some} bottles of beer on the wall {some} bottles of beer Take one down, pass it around {less} bottles of beer on the wall

for bottles in range(99,0,-1):

   print verse.format(some=bottles, less=bottles-1) </lang>

"Clever" generator expression

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

Enhanced "Clever" generator expression using lambda

<lang python>a = lambda n: "%u bottle%s of beer on the wall\n" % (n, "s"[n==1:]) print "\n".join(a(x)+a(x)[:-13]+"\nTake one down, pass it around\n"+a(x-1) for x in xrange(99, 0, -1))</lang>

Using a generator expression (Python 3)

<lang python>#!/usr/bin/env python3 """\ {0} {2} of beer on the wall {0} {2} of beer Take one down, pass it around {1} {3} of beer on the wall """ print("\n".join(

   __doc__.format(
       i, i - 1,
       "bottle" if i == 1 else "bottles",
       "bottle" if i - 1 == 1 else "bottles"
   ) for i in range(99, 0, -1)

), end="")</lang>

A wordy version

<lang python>ones = ( , 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine' ) prefixes = ('thir', 'four', 'fif', 'six', 'seven', 'eigh', 'nine') tens = [, , 'twenty' ] teens = ['ten', 'eleven', 'twelve'] for prefix in prefixes:

   tens.append(prefix + 'ty')
   teens.append(prefix +'teen')

tens[4] = 'forty'

def number(num):

   "get the wordy version of a number"
   ten, one = divmod(num, 10)
   if ten == 0 and one == 0:
       return 'no'
   elif ten == 0:
       return ones[one]
   elif ten == 1:
       return teens[one]
   elif one == 0:
       return tens[ten]
   else:
       return "%s-%s" % (tens[ten], ones[one])

def bottles(beer):

   "our rephrase"
   return "%s bottle%s of beer" % ( 
           number(beer).capitalize(), 's' if beer > 1 else 
   )

onthewall = 'on the wall' takeonedown = 'Take one down, pass it around' for beer in range(99, 0, -1):

   print bottles(beer), onthewall
   print bottles(beer)
   print takeonedown
   print bottles(beer-1), onthewall
   print</lang>

String Formatting

<lang python>for n in xrange(99, 0, -1):

   ##  The formatting performs a conditional check on the variable.
   ##  If it formats the first open for False, and the second for True
   print n, 'bottle%s of beer on the the wall.' % ('s', )[n == 1]
   print n, 'bottle%s of beer.' % ('s', )[n == 1]
   print 'Take one down, pass it around.'
   print n - 1, 'bottle%s of beer on the wall.\n' % ('s', )[n - 1 == 1]</lang>

Qore

Simple Solution

<lang qore>#!/usr/bin/env qore

%enable-all-warnings

for (my $i = 99; $i > 0; $i--) {

   printf("%d bottles of beer on the wall\n", $i);
   printf("%d bottles of beer\n", $i);
   printf("take one down, pass it around\n");
   printf("%d bottles of beer on the wall\n", $i);

}</lang>

Concurrent (Unordered) Solution

<lang qore>#!/usr/bin/env qore

%enable-all-warnings %require-types

  1. global variables (truly shared among threads) must be declared with "our" keyword

%require-our

our Counter $count();

sub t() {

 on_exit { 
       $count.dec();
 }
 my int $i = gettid()-1;
 printf("%d bottles of beer on the wall\n", $i);
 printf("%d bottles of beer\n", $i);
 printf("take one down, pass it around\n");
 printf("%d bottles of beer on the wall\n", $i);

}

  1. -- following run by main thread

for (my int $i = 99; $i > 0; $i--) {

 $count.inc();
 background t();

}

$count.waitForZero();</lang>

Quill

<lang quill>bottles := void(int count) {

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

}; 99 bottles</lang>

R

Simple looping solution

<lang rsplus>#a naive function to sing for N bottles of beer...

song = function(bottles){

 for(i in bottles:1){ #for every integer bottles, bottles-1 ... 1
     
   cat(bottles," bottles of beer on the wall \n",bottles," bottles of beer \nTake one down, pass it around \n",
       bottles-1, " bottles of beer on the wall \n"," \n" ,sep="")       #join and print the text (\n means new line)
   
       bottles = bottles - 1 #take one down...
   
 }
 

}

song(99)#play the song by calling the function</lang>

Vector solutions

<lang rsplus>#only one line! cat(paste(99:1,ifelse((99:1)!=1," bottles"," bottle")," of beer on the wall\n",99:1,ifelse((99:1)!=1," bottles"," bottle")," of beer\n","Take one down, pass it around\n",98:0,ifelse((98:0)!=1," bottles"," bottle")," of beer on the wall\n\n",sep=""),sep="")

  1. alternative

cat(paste(lapply(99:1,function(i){paste(paste(rep(paste(i,' bottle',if(i!=1)'s',' of beer',sep=),2),collapse =' on the wall\n'),'Take one down, pass it around',paste(i-1,' bottle',if(i!=2)'s',' of beer on the wall',sep=), sep='\n')}),collapse='\n\n'))</lang>

Racket

<lang racket>

  1. lang racket

(define (sing bottles)

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

(sing 100) </lang>

Rascal

<lang rascal> module demo::basic::Bottles

import IO;

str bottles(0) = "no more bottles"; str bottles(1) = "1 bottle"; default str bottles(int n) = "<n> bottles";

public void sing(){

 for(n <- [99 .. 1]){
      println("<bottles(n)> of beer on the wall, <bottles(n)> of beer.");
      println("Take one down, pass it around, <bottles(n-1)> of beer on the wall.\n");
 }  
 println("No more bottles of beer on the wall, no more bottles of beer.");
 println("Go to the store and buy some more, 99 bottles of beer on the wall.");

} </lang>

Raven

<lang raven>99 0 1 range each as $i

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

Last couple of stanzas are:

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

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

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

REBOL

<lang REBOL>rebol [

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

]

The 'bottles' function maintains correct grammar.

bottles: func [n /local b][ b: either 1 = n ["bottle"]["bottles"] if 0 = n [n: "no"] reform [n b] ]

for n 99 1 -1 [print [ bottles n "of beer on the wall" crlf bottles n "of beer" crlf "Take one down, pass it around" crlf bottles n - 1 "of beer on the wall" crlf ]]</lang>

Output (selected highlights):

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

Retro

This is based on the Forth example.

<lang Retro>[ dup "%d bottles" puts ] [ "1 bottle" puts ] [ "no more bottles" puts ] create bottles , , ,

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

99 verses bye</lang>

REXX

<lang rexx>/*REXX pgm displays words to the song "99 Bottles of Beer on the Wall". */

 do j=99 by -1 to 1                        /*start countdown | singdown*/
 say j 'bottle's(j) "of beer on the wall," /*sing the #bottles of beer.*/
 say j 'bottle's(j) "of beer."             /* ... and the refrain.     */
 say 'Take one down, pass it around,'      /*get a bottle and share it.*/
 n=j-1                                     /*N is #bottles we have now.*/
 if n==0 then n='no'                       /*use  "no"  instead of  0. */
 say n 'bottle's(n) "of beer on the wall." /*sing beer bottle inventory*/
 say                                       /*blank line between verses.*/
 end   /*j*/

say 'No more bottles of beer on the wall,' /*Finally! The last verse.*/ say 'no more bottles of beer.' /*so sad ... */ say 'Go to the store and buy some more,' /*replenishment of the beer.*/ say '99 bottles of beer on the wall.' /*All is well in the tavern.*/ exit /*we're done & also sloshed.*/ /*───────────────────────────────────S subroutine───────────────────────*/ s: if arg(1)=1 then return ; return 's' /*a simple pluralizer funct.*/</lang> output Below is the first and last three verses of the song.

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

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

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

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

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

RPL/2

Simple solution

<lang rpl/2>BEER <<

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

>>

PLURAL <<

   " bottle" + over if 1 <> then "s" + end " of beer" +

>></lang>

Recursive and multithreaded solution

<lang rpl/2>BOTTLES <<

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

>>

RECURSIVE <<

       while
               dup
       repeat
               1 - dup dup ->str
               if over 1 > then " bottles " else " bottle " end +
               "of beer" + 2 ->list dup
               // Child send datas to parent process.
               send send
               // Recursive function is caught.
               RECURSIVE
       end

>></lang>

Ruby

<lang ruby>plural = 's' 99.downto(1) do |i|

 puts "#{i} bottle#{plural} of beer on the wall,"
 puts "#{i} bottle#{plural} of beer"
 puts "Take one down, pass it around!"
 plural =  if i - 1 == 1
 if i > 1
   puts "#{i-1} bottle#{plural} of beer on the wall!"
   puts
 else
   puts "No more bottles of beer on the wall!"
 end

end</lang>

Ruby has variable traces, so we can do <lang ruby>trace_var :$bottle_num do |val|

 $bottles = %Q{#{val == 0 ? 'No more' : val.to_s} bottle#{val == 1 ?  : 's'}}

end

($bottle_num = 99).times do

 puts "#{$bottles} of beer on the wall"
 puts "#{$bottles} of beer"
 puts "Take one down, pass it around"
 $bottle_num -= 1
 puts "#{$bottles} of beer on the wall"
 puts ""

end</lang> or... <lang ruby>def bottles(of_beer, ending)

 puts "#{of_beer} bottle#{ending} of beer on the wall,"
 puts "#{of_beer} bottle#{ending} of beer"
 puts "Take one down, pass it around!"

end

99.downto(0) do |left|

 if left > 1
   bottles(left, "s")
 elsif left == 1
   bottles(left, "")
 else
   puts "No more bottles of beer on the wall!"
 end

end</lang> or... <lang ruby>def bottles(beer, wall = false)

 "#{beer>0 ? beer : "no more"} bottle#{"s" if beer!=1} of beer#{" on the wall" if wall}"

end

99.downto(0) do |remaining|

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

end</lang>

Rust

Works with: rustc version 0.9-pre (80991bb 2013-11-29 14:01:48 -0800)

<lang Rust>// rust is changing fast, so this will probably not work in later versions

use std::iter::range_step_inclusive;

fn main() {

 for num_bottles in range_step_inclusive(99, 1, -1) {
   sing_bottles_line(num_bottles, true);
   sing_bottles_line(num_bottles, false);
   println("Take one down, pass it around...");
   sing_bottles_line(num_bottles - 1, true);
   println("-----------------------------------");
 }

}

fn sing_bottles_line(num_bottles: int, on_the_wall: bool) {

 // the print! macro uses a built in internationalization formatting language
 // check out the docs for std::fmt
 print!("{0, plural, =0{No bottles} =1{One bottle} other{# bottles}} of beer", num_bottles as uint);
 
 // this is to demonstrate the select "method"
 // it's probably not the best way to do it
 // it needs a &str so I had to use that tmp variable to trick it
 // hopefully someone else can fix it for me
 let tmp: &str = on_the_wall.to_str();
 println!("{0, select, true{ on the wall} other{}}!", tmp);

} </lang>

Sather

<lang sather>class MAIN is

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

end;</lang>

Scala

See 99 Bottles of Beer/Scala

Scheme

Works with: Chicken Scheme

<lang scheme>(define (bottles x) (format #t "~a bottles of beer on the wall~%" x) (format #t "~a bottles of beer~%" x) (format #t "Take one down, pass it around~%") (format #t "~a bottles of beer on the wall~%" (- x 1)) (if (> (- x 1) 0) (bottles (- x 1))))</lang>

Scratch

sed

<lang sed>s/.*/99 bottles of beer on the wall/ h

b

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

Seed7

<lang seed7>$ include "seed7_05.s7i";

const proc: main is func

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

Shiny

<lang shiny>for 99 i:99-a

   s: if i > 1 's' end
   if i > 0 and i < 99 switch
       if i = 6  say "A six-pack on the wall!\n" break
       if i = 24 say "A carton on the wall!\n"   break
       say "$i bottle$s of beer on the wall!\n"
   ends
   say "$i bottle$s of beer on the wall,"
   say "$i bottle$s of beer!"
   say "Take one down, pass it around!"

end say "Aww...no more bottles of beer on the wall... it must be your shout :)"</lang>

Sidef

<lang ruby>99.downto(0).each { |i|

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

};</lang>

Simpler: <lang ruby>99.downto(2).each { | n |

 say "#{n} bottles of beer on the wall, #{n} bottles of beer!";
 say "Take one down, pass it around, #{n - 1} bottle#{n > 2 ? 's' : } of beer on the wall.\n";

};

say "One bottle of beer on the wall, one bottle of beer!"; say "Take one down, pass it around, no more bottles of beer on the wall.";</lang>

Slate

<lang slate>n@(Integer traits) bottleVerse [| nprinted |

 nprinted: n printString ; ' bottle' ; (n > 1 ifTrue: ['s'] ifFalse: []) ; ' of beer'.
 inform: nprinted ; ' on the wall.'.
 inform: nprinted.
 inform: 'Take one down, pass it around.'.
 inform: nprinted ; ' on the wall.'.

].

x@(Integer traits) bottles [

 x downTo: 0 do: #bottleVerse `er

].

99 bottles.</lang>

Smalltalk

A straightforward approach: <lang smalltalk>Smalltalk at: #sr put: 0 ; at: #s put: 0 ! sr := Dictionary new. sr at: 0 put: ' bottle' ;

  at: 1 put: ' bottles' ;
  at: 2 put: ' of beer' ;
  at: 3 put: ' on the wall' ;
  at: 4 put: 'Take one down, pass it around' !

99 to: 0 by: -1 do: [:v | v print.

        ( v == 1 ) ifTrue: [ s := 0. ] 

ifFalse: [ s := 1. ]. Transcript show: (sr at:s) ; show: (sr at:2) ; show: (sr at:3) ; cr. v print. Transcript show: (sr at:s) ; show: (sr at:2) ; cr. (v ~~ 0) ifTrue: [ Transcript show: (sr at:4) ; cr. ].

  ].</lang>

SNOBOL4

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

Function

Works with: Macro Spitbol
Works with: CSnobol

Function version with string composition. Function returns one verse for x bottles. Correctly handles bottle/bottles. <lang SNOBOL4> define('bottles(x)')

       nl = char(13) char(10) ;* Win/DOS, change as needed
       s2 = ' of beer'; s3 = ' on the wall'
       s4 = 'Take one down, pass it around'
       s5 = 'Go to the store, get some more' :(bottles_end)

bottles s1 = (s1 = ' Bottle') ne(x,1) 's'

       output = nl x s1 s2 s3 nl x s1 s2
       x = gt(x,0) x - 1 :f(done)
       s1 = (s1 = ' Bottle') ne(x,1) 's'
       output = s4 nl x s1 s2 s3 :(return)

done output = s5 nl 99 s1 s2 s3 :(return) bottles_end

  • # Test and display, only 2 bottles!
       n = 2

loop bottles(n); n = gt(n,0) n - 1 :s(loop) end</lang>

Output:

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

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

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

SNUSP

<lang snusp> /=!/===========!/==+++++++++# +9

  |  |  /=!/=====@/==@@@+@+++++# +48 (itoa)
  |  |  |  |  /==!/==@@@@=++++#  +32 (space)
  |  |  |  |  |   \==@@++\!+++++++++++++\!+++++\ 
  9  9 '9  9' space     'b'            'o'    't'
$@/>@/>@/>@/>@/>========@/>============@/>====@/>++++++++++  \n  setup

/====================================loop=====>\!=>\!<<<<<<<< / \@\@\>cr.@\< ?\<->+++++++++>->+++++++++\ | |

 ! |     |   \===-========>=>-==BCD==!\< @\< ?/< ?/# no more beer!
 /=|=====|================================/
 | |     \<++t.<<----a.>----k.<++++e.<_.>>++++o.-n.< e.<_.>-d.>+o.>+++w.<-n.<<_.\ 
 | |     /                                                                      /
 | |     \>---a.>n.<+++d.<_.>>++p.<---a.>>----s.s.<<<_.>>-------i.>+t.<<<_.\ 
 | |     /                                                                 /
 | |     \>a.>>--r.<++++++o.>+++u.<-n.<+++d.>>>cr.<-T<+O<--B<<<#
 | !
 \@\<<<_.>>o.-n.<<_.>>>++t.<<+++h.---e.<_.>>>+++w.<<----a.>--l.l.>>CR.<---T<+++O<+B<<<#
   |
   \9.>9.>_.>B.>O.>T.t.<---l.<+++e.>>-s.<<<_.>>+++O.<+f.<_.>----b.+++e.E.>>-R.#</lang>

Sparkling

<lang sparkling>var bottles = 99;

do {

   printf("%u bottles of beer on the wall\n", bottles);
   printf("%u bottles of beer\n", bottles);
   printf("Take one down, pass it around\n");
   printf("%u bottles of beer on the wall\n\n", --bottles);

} while(bottles > 1);

printf("1 bottle of beer on the wall\n1 bottle of beer\nTake it down, pass it around\n0 bottles of beer on the wall\n");</lang>

SQL

<lang SQL>


DELIMITER $$ DROP PROCEDURE IF EXISTS bottles_$$ CREATE pROCEDURE `bottles_`(inout bottle_count int, inout song text) BEGIN declare bottles_text varchar(30);


IF bottle_count > 0 THEN


   if bottle_count != 1 then
   set bottles_text :=  ' bottles of beer ';
   else set bottles_text = ' bottle of beer ';
   end if;
  
   SELECT concat(song, bottle_count, bottles_text, ' \n') INTO song;
   SELECT concat(song, bottle_count, bottles_text,  'on the wall\n') INTO song;
   SELECT concat(song, 'Take one down, pass it around\n') into song;
   SELECT concat(song, bottle_count -1 , bottles_text,  'on the wall\n\n') INTO song;
   set bottle_count := bottle_count -1;
   CALL bottles_( bottle_count, song);
 END IF;

END$$

set @bottles=99; set max_sp_recursion_depth=@bottles; set @song=; call bottles_( @bottles, @song); select @song; </lang>

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

<lang SQL> CREATE PROCEDURE bottles @bottle_count int, @song varchar(MAX)

AS BEGIN

declare @bottles_text VARCHAR(MAX);


IF @bottle_count > 0

BEGIN
   IF @bottle_count != 1

BEGIN SET @bottles_text = ' bottles of beer ';

   END
   ELSE 
   BEGIN

SET @bottles_text = ' bottle of beer '; END


   SET @song = @song + CAST(@bottle_count AS VARCHAR) + @bottles_text + '\n';
   
   SET @song = @song + CAST(@bottle_count AS VARCHAR) + @bottles_text +  'on the wall\n'
   SET @song = @song + 'Take one down, pass it around\n'
   SET @song = @song + CAST((@bottle_count - 1) AS VARCHAR) + @bottles_text +  'on the wall\n'
   
   
   SET @bottle_count = (@bottle_count - 1);
   


  EXEC bottles @bottle_count, @song

END ELSE select @song AS 'RESULT' END

/***** AND IN ORDER TO CALL PROCEDURE:

        • /

EXECUTE bottles 31, ;

</lang>

Squirrel

<lang squirrel> function rec(bottles) {

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

}

rec(99); </lang>

Standard ML

<lang sml>fun bottles 0 = ()

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

Suneido

<lang Suneido>i = 99 while (i > 0)

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

Tcl

<lang tcl>set s "s"; set ob "of beer"; set otw "on the wall"; set more "Take one down and pass it around" for {set n 100} {$n ne "No more"} {} { switch -- [incr n -1] { 1 {set s ""} 0 {set s "s"; set n "No more"; set more "Go to the store and buy some more"} } lappend verse ". $n bottle$s $ob $otw.\n" lappend verse "\n$n bottle$s $ob $otw, [string tolower $n] bottle$s $ob.\n$more" } puts -nonewline [join [lreplace $verse 0 0] ""][lindex $verse 0]</lang> Version which converts numbers to words, optimized for script length while retaining readability: <lang tcl>proc 0-19 {n} {

   lindex {"no more" one two three four five six seven eight nine ten eleven
           twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen} $n

}

proc TENS {n} {

   lindex {twenty thirty fourty fifty sixty seventy eighty ninety} [expr {$n - 2}]

}

proc num2words {n} {

   if {$n < 20} {return [0-19 $n]}
   set tens [expr {$n / 10}]
   set ones [expr {$n % 10}]
   if {$ones == 0} {return [TENS $tens]}
   return "[TENS $tens]-[0-19 $ones]"

}

proc get_words {n} {

   return "[num2words $n] bottle[expr {$n != 1 ? "s" : ""}] of beer"

}

for {set i 99} {$i > 0} {incr i -1} {

   puts [string totitle "[get_words $i] on the wall, [get_words $i]."]
   puts "Take one down and pass it around, [get_words [expr {$i - 1}]] on the wall.\n"

}

puts "No more bottles of beer on the wall, no more bottles of beer." puts "Go to the store and buy some more, 99 bottles of beer on the wall."</lang> See also 99 Bottles of Beer/Tcl

Thyrd

main
detail

TIScript

<lang javascript> var beer = 99; while (beer > 0) {

stdout.printf( "%d bottles of beer on the wall\n", beer);
stdout.printf( "%d bottles of beer\n", beer);
stdout.println( "Take one down, pass it around" );
stdout.printf( "%d bottles of beer on the wall\n", --beer );

} </lang>

TorqueScript

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

TUSCRIPT

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

TXR

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

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

@ (end) @ (or) @ (output) Take one down and pass it around @number_less_1 bottles of beer on the wall

@ (end) @ (end) @(end)</lang>

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

<lang txr>@(next :list @(mapcar* (fun tostring) (repeat (range 99 0 -1))))</lang>

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

UNIX Shell

Works with: Bourne Shell

<lang bash>#!/bin/sh

i=99 s=s

while [ $i -gt 0 ]; do

       echo "$i bottle$s of beer on the wall"
       echo "$i bottle$s of beer

Take one down, pass it around"

       # POSIX allows for $(( i - 1 )) but some older Unices didn't have that
       i=`expr $i - 1`

[ $i -eq 1 ] && s= || s=s

       echo "$i bottle$s of beer on the wall

" done</lang>

Works with: Bash
Works with: ksh93
Works with: zsh

<lang bash>bottles() {

 beer=$1
 [ $((beer)) -gt 0 ] && echo -n $beer ||  echo -n "No more"
 echo -n " bottle"
 [ $((beer)) -ne 1 ] && echo -n "s"
 echo -n " of beer"

}

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

 ((remaining=i))
 echo "$(bottles $remaining) on the wall"
 echo "$(bottles $remaining)"
 if [ $((remaining)) -eq 0 ]; then
   echo "Go to the store and buy some more"
   ((remaining+=99))
 else
   echo "Take one down, pass it around"
   ((remaining--))
 fi
 echo "$(bottles $remaining) on the wall"
 echo

done</lang>

C Shell

<lang csh>@ i=99 set s=s while ($i > 0) echo "$i bottle$s of beer on the wall" echo "$i bottle$s of beer" echo "Take one down, pass it around" @ i = $i - 1 if ($i == 1) then set s= else set s=s endif echo "$i bottle$s of beer on the wall" echo "" end</lang>

es

<lang es>i = 99 s = s while {test $i -gt 0} { echo $i bottle$s of beer on the wall echo $i bottle$s of beer echo Take one down, pass it around i = `{expr $i - 1} if {test $i -eq 1} {s = } {s = s} echo $i bottle$s of beer on the wall echo }</lang>

UnixPipes

<lang bash># Unix Pipes, avoiding all the turing complete sub programs like sed, awk,dc etc. mkdir 99 || exit 1 trap "rm -rf 99" 1 2 3 4 5 6 7 8

(cd 99

  mkfifo p.b1 p.b2 p.verse1 p.wall p.take
  yes "on the wall" > p.wall &
  yes "Take one down and pass it around, " > p.take &
  (yes "bottles of beer" | nl -s\ | head -n 99 | tac | head -n 98 ;
   echo "One bottle of beer";
   echo "No more bottles of beer") | tee p.b1 p.b2 |
  paste -d"\ " - p.wall p.b1 p.take | head -n 99 > p.verse1 &
  cat p.b2 | tail -99 | paste -d"\ " p.verse1 - p.wall | head -n 99

) rm -rf 99</lang>

Ursala

<lang Ursala>#import nat

  1. each function takes a natural number to a block of text

quantity = # forms the plural as needed

~&iNC+ --' of beer'+ ~&?(

  1?=/'1 bottle'! --' bottles'+ ~&h+ %nP,
  'no more bottles'!)

verse =

^(successor,~&); ("s","n"). -[

  -[quantity "s"]- on the wall, -[quantity "s"]-,
  Take one down and pass it around, -[quantity "n"]- on the wall.]-

refrain "n" =

-[

  No more bottles of beer on the wall, -[quantity 0]-.
  Go to the store and buy some more, -[quantity "n"]- on the wall.]-

whole_song "n" = ~&ittt2BSSL (verse*x iota "n")--<refrain "n">

  1. show+

main = whole_song 99</lang>

V

<lang v>[bottles

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

99 bottles</lang>

Vala

<lang vala>void main() {

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

}</lang>

VBA

This version uses tail recursion and inline if-statements, plus a Static variable to count the number of bottles emptied.

<lang vb>Public Function countbottles(n As Integer, liquid As String) As String

 countbottles = IIf(n > 1, Format$(n), IIf(n = 0, "no more", "one")) & " bottle" & IIf(n = 1, "", "s") & " of " & liquid

End Function

Public Sub drink(fullbottles As Integer, Optional liquid As String = "beer") Static emptybottles As Integer

 Debug.Print countbottles(fullbottles, liquid) & " on the wall"
 Debug.Print countbottles(fullbottles, liquid)
 If fullbottles > 0 Then
   Debug.Print "take " & IIf(fullbottles > 1, "one", "it") & " down, pass it around"
   Debug.Print countbottles(fullbottles - 1, liquid) & " on the wall"
   Debug.Print
   emptybottles = emptybottles + 1
   drink fullbottles - 1, liquid
 Else
   Debug.Print "go to the store and buy some more"
   Debug.Print countbottles(emptybottles, liquid) & " on the wall"
 End If

End Sub</lang>

Usage: type "drink 99" in the Immediate window of the VBA editor. If you're not a beer drinker, you can specify your own favourite drink as the second argument; for example:

drink 3, "Johnnie Walker"

3 bottles of Johnnie Walker on the wall
3 bottles of Johnnie Walker
take one down, pass it around
2 bottles of Johnnie Walker on the wall

2 bottles of Johnnie Walker on the wall
2 bottles of Johnnie Walker
take one down, pass it around
one bottle of Johnnie Walker on the wall

one bottle of Johnnie Walker on the wall
one bottle of Johnnie Walker
take it down, pass it around
no more bottles of Johnnie Walker on the wall

no more bottles of Johnnie Walker on the wall
no more bottles of Johnnie Walker
go to the store and buy some more
3 bottles of Johnnie Walker on the wall

VBScript

Simple Method

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

function pluralBottles( n ) select case n case 1 pluralBottles = "one bottle" case 0 pluralBottles = "no more bottles" case else pluralBottles = n & " bottles" end select end function

song 3</lang> Outputs: <lang vbscript>3 bottles of beer on the wall 3 bottles of beer take one down and pass it round 2 bottles of beer on the wall

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

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

no more bottles of beer on the wall no more bottles of beer go to the store and buy some more 3 bottles of beer on the wall</lang>

Regular Expressions and Embedded Scripting

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

<lang vb>function pluralBottles( n ) select case n case 1 pluralBottles = "one bottle" case 0 pluralBottles = "no more bottles" case else pluralBottles = n & " bottles" end select end function

function eef( b, r1, r2 ) if b then eef = r1 else eef = r2 end if end function

Function evalEmbedded(sInput, sP1) dim oRe, oMatch, oMatches dim sExpr, sResult Set oRe = New RegExp 'Look for expressions as enclosed in braces oRe.Pattern = "{(.+?)}" sResult = sInput do Set oMatches = oRe.Execute(sResult) if oMatches.count = 0 then exit do for each oMatch in oMatches '~ wscript.echo oMatch.Value for j = 0 to omatch.submatches.count - 1 sExpr = omatch.submatches(j) sResult = Replace( sResult, "{" & sExpr & "}", eval(sExpr) ) next next loop evalEmbedded = sResult End Function

sub sing( numBottles ) dim i for i = numBottles to 0 step -1 if i = 0 then wscript.echo evalEmbedded("no more bottles of beer on the wall" & vbNewline & _ "no more bottles of beer" & vbNewline & _ "go to the store and buy some more" & vbNewline & _ "{pluralBottles(sP1)} of beer on the wall" & vbNewline, numBottles) else wscript.echo evalEmbedded("{pluralBottles(sP1)} of beer on the wall" & vbNewline & _ "{pluralBottles(sP1)} of beer" & vbNewline & _ "take {eef(sP1=1,""it"",""one"")} down and pass it round" & vbNewline & _ "{pluralBottles(sP1-1)} of beer on the wall" & vbNewline, i) end if next end sub

sing 3</lang>

Visual Prolog

<lang visual prolog> implement main

   open core, std, console

class predicates

   bottles : (integer) -> string procedure (i).

clauses

   bottles(1) = "bottle" :- !.
   bottles(_) = "bottles".
   run():-
       init(),
       foreach B = downTo(99,1) do
           write(B," ",bottles(B), " of beer on the wall,\n"),
           write(B," ",bottles(B), " of beer,\n"),
           write("Take one down, pass it around,\n"),
           write(B-1," ",bottles(B-1)," of beer on the wall.\n\n")
       end foreach,
       succeed(). 

end implement main

goal

   mainExe::run(main::run).

</lang>

Vox

<lang vox> // translated from <http://rosettacode.org/wiki/99_Bottles_of_Beer#JavaScript>

local beer; while((beer = typeof beer == "null" ? 99 : beer) > 0)

   println(
       beer + " bottle" +
       (beer != 1 ? "s" : "") +
       " of beer on the wall\n" + beer + " bottle" +
       (beer != 1 ? "s" : "") +
       " of beer\nTake one down, pass it around\n" +
       (--beer) + " bottle" +
       (beer != 1 ? "s" : "") + " of beer on the wall\n"
   );

</lang>

Wart

<lang python>def (beer n)

 when (n > 0)
   prn n " bottles of beer on the wall"
   prn n " bottles of beer"
   prn "take one down, pass it around"
   prn n-1 " bottles of beer on the wall"
   prn ""
   beer n-1</lang>

Whenever

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

Wortel

<lang wortel>!console.log @let {

 beer :&@?n{
   0 '0 bottles of beer on the wall\n0 bottles of beer\nbetter go to the store and buy some more.'
   1 '1 bottle of beer on the wall\n1 bottle of beer\nTake one down, pass it around'
   "{n} bottles of beer on the wall\n{n} bottles of beer\nTake one down, pass it around"
 }
 @join '\n' !*beer @range [99 0]

} </lang>

Wrapl

<lang wrapl>MOD Bottles;

IMP IO.Terminal USE Out; IMP Std.String;

VAR i, s <- "s", ob <- "of beer", otw <- "on the wall",

   more <- "Take one down and pass it around", verse <- [];

EVERY i <- 99:to(0,-1) DO (

   (i = 1) & (s <- "");
   (i = 0) & (s <- "s"; i <- "No more"; more <- "Go to the store and buy some more");
   verse:put('. {i} bottle{s} {ob} {otw}.\n');
   verse:put('\n{i} bottle{s} {ob} {otw}, {(i@String.T):lower} bottle{s} {ob}.\n{more}');

);

Out:write(verse[2,0]@(String.T, "") + verse[1]);

END Bottles.</lang>

X86 Assembly

Using Windows/MASM32. <lang asm>.386 .model flat, stdcall option casemap :none

include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\user32.inc includelib \masm32\lib\kernel32.lib includelib \masm32\lib\masm32.lib includelib \masm32\lib\user32.lib

.DATA

buffer db 1024 dup(?)
str1 db "%d bottles of beer on the wall.",10,13,0
str2 db "%d bottles of beer",10,13,0
str3 db "Take one down, pass it around",10,13,0
str4 db "No more bottles of beer on the wall!",10,13,0
nline db 13,10,0
bottles dd 99

.CODE

start:
 INVOKE wsprintfA, offset buffer, offset str1, [bottles]
 INVOKE StdOut, offset buffer
 INVOKE wsprintfA, offset buffer, offset str2, [bottles]
 INVOKE StdOut, offset buffer
 INVOKE StdOut, offset str3
 DEC [bottles]
 INVOKE wsprintfA, offset buffer, offset str1, [bottles]
 INVOKE StdOut, offset buffer
 INVOKE StdOut, offset nline
 CMP [bottles], 1
 JNE start
 INVOKE StdOut, offset str4
 INVOKE ExitProcess, 0
end start</lang>

XPL0

<lang XPL0>code IntOut=11, Text=12; int B; [B:= 99; repeat IntOut(0, B); Text(0, " bottles of beer on the wall^M^J");

       IntOut(0, B);  Text(0, " bottles of beer^M^J");
       Text(0, "Take one down, pass it around^M^J");
       B:= B-1;
       IntOut(0, B);  Text(0, " bottles of beer on the wall^M^J^J");

until B=0; ]</lang>

Yorick

Looped version

<lang yorick>bottles = 99; while(bottles) {

   write, format=" %d bottles of beer on the wall\n", bottles;
   write, format=" %d bottles of beer\n", bottles;
   write, "Take one down, pass it around";
   write, format=" %d bottles of beer on the wall\n\n", --bottles;

}</lang>

Vectorized version

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