% T version of 99 Bottles of beer (Bottles.t)
% http://www.programmersheaven.com/zone22/cat254/16480.htm
% Philipp Winterberg, http://www.winterbergs.de
program
var b : int := 99
loop
exit when b = 0
put b, " bottle(s) of beer on the wall,"
put b, " bottle(s) of beer."
put "Take one down, pass it around,"
b := b - 1
put b, " bottle(s) of beer on the wall."
end loop
end program
module bottles(t3x, string);
! 99 bottles of beer on the wall
! 2002-05-03 Nils M Holm <nmh@t3x.org>
#packstrings;
object t[t3x], str[string];
writes(s) t.write(T3X.SYSOUT, s, str.length(s));
writef(s, v) do var tmp::40;
writes(str.format(tmp, s, v));
writes(t.newline(tmp));
end
bottles(n, w, c) do var tmp::3;
writef("%s bottle%s of beer%s%c",
[(n-> str.format(tmp, "%d", [(n)]):
c='.'-> "no more": "No more"),
(n=1-> "": "s"),
(w-> " on the wall": ""),
(c)]);
end
do var i;
for (i=99, 0, -1) do
bottles(i, 1, ',');
bottles(i, 0, '.');
writef("Take one down and pass it around,", 0);
bottles(i-1, 1, '.');
writef("", 0);
end
bottles(0, 1, ',');
bottles(0, 0, '.');
writef("Go to the store, buy some more,", 0);
writef("99 bottles of beer on the wall.", 0);
end
?TACL ROUTINE
== TACL (Tandem Advanced Command Language)
== This is one 'Shell' scripting language of HP/Compaq NonStop Systems
== formerly known as Tandem
==
== Dirk Grabenkamp, 25. Sep 2002 (Dirk.Grabenkamp@GMX.DE)
==
#FRAME
#PUSH #OUTFORMAT
#SET #OUTFORMAT PRETTY
#PUSH NrOfBottles Bottles
#SET NrOfBottles 99
#SET Bottles bottles
[#LOOP |DO|
#OUTPUT [NrOfBottles] [Bottles] of beer on the wall, [NrOfBottles] [Bottles] of beer
#OUTPUT /HOLD/ Take one down and pass it around,
#SET NrOfBottles [#COMPUTE NrOfBottles - 1]
[#CASE [NrOfBottles]
|1| #SET Bottles bottle
|0| #SET Bottles bottles
#SET NrOfBottles no more
|OTHERWISE|
]
#OUTPUT ~_[NrOfBottles] [Bottles] of beer on the wall.
|UNTIL| (NrOfBottles '=' "no more")
]
#UNFRAME
// TADS 3 (Text Adventure Development System) is a language
// for crafting interactive fiction. More information can
// be found at http://www.tads.org/.
// 99 bottles of beer on the wall.
// 17 June 2002 Jim Nelson <jim_nelson@mindspring.com>
main(args)
{
local bottles = 99;
local number = bottles;
local plural = 's';
for(;;)
{
"<<number>> bottle<<plural>> of beer on the wall,\n";
"<<number>> bottle<<plural>> of beer,\n";
if(bottles == 0)
{
break;
}
"Take <<(bottles != 1) ? 'one' : 'it'>> down, pass it around,\n";
bottles--;
if(bottles > 1)
{
plural = 's';
number = bottles;
}
else if(bottles == 1)
{
plural = '';
number = 'One more';
}
else
{
// zero
plural = 's';
number = 'No more';
}
"<<number>> bottle<<plural>> of beer on the wall.\n\b";
}
"Go to the store, buy some more,\n";
"99 bottles of beer on the wall.\n\b";
}
99 Bottles in Tandem TAL (Transaction Application Language):
?NOLIST
?SOURCE $SYSTEM.SYSTEM.EXTDECS0 (FILE_OPEN_,FILE_CLOSE_,WRITE,INITIALIZER,
? PROCESS_STOP_,NUMOUT,PROCESS_GETINFO_);
INT MYTERM^NAME[0:11], MYTERM^NUM, MYTERM^LEN, ERROR, NUM^BOTTLES;
STRING .LINE1[0:37], .LINE2[0:32], .MSG^PTR;
?LIST
PROC BOTTLES MAIN;
BEGIN
CALL INITIALIZER(,,,,,);
ERROR := PROCESS_GETINFO_(,,,,,MYTERM^NAME:24,MYTERM^LEN,,,,,,,,,);
ERROR := FILE_OPEN_(MYTERM^NAME:MYTERM^LEN,MYTERM^NUM);
IF ERROR <> 0 THEN CALL PROCESS_STOP_(,,1);
NUM^BOTTLES := 99;
LINE1 ':=' " BOTTLES OF BEER ON THE WALL";
CALL NUMOUT(LINE1[0],NUM^BOTTLES,10,2);
LINE2 ':=' "TAKE ONE DOWN AND PASS IT AROUND";
WHILE (NUM^BOTTLES > 0) DO
BEGIN
CALL WRITE(MYTERM^NUM, LINE1, 30);
CALL WRITE(MYTERM^NUM, LINE1, 18);
CALL WRITE(MYTERM^NUM, LINE2, 32);
NUM^BOTTLES := NUM^BOTTLES - 1;
IF (NUM^BOTTLES = 1) THEN LINE1 ':=' " BOTTLE OF BEER ON THE WALL ";
IF (NUM^BOTTLES > 0) THEN
CALL INITIALIZER(,,,,,);
ERROR := PROCESS_GETINFO_(,,,,,MYTERM^NAME:24,MYTERM^LEN,,,,,,,,,);
ERROR := FILE_OPEN_(MYTERM^NAME:MYTERM^LEN,MYTERM^NUM);
IF ERROR <> 0 THEN CALL PROCESS_STOP_(,,1);
NUM^BOTTLES := 99;
LINE1 ':=' " BOTTLES OF BEER ON THE WALL";
CALL NUMOUT(LINE1[0],NUM^BOTTLES,10,2);
LINE2 ':=' "TAKE ONE DOWN AND PASS IT AROUND";
WHILE (NUM^BOTTLES > 0) DO
BEGIN
CALL WRITE(MYTERM^NUM, LINE1, 30);
CALL WRITE(MYTERM^NUM, LINE1, 18);
CALL WRITE(MYTERM^NUM, LINE2, 32);
NUM^BOTTLES := NUM^BOTTLES - 1;
IF (NUM^BOTTLES = 1) THEN LINE1 ':=' " BOTTLE OF BEER ON THE WALL ";
IF (NUM^BOTTLES > 0) THEN
BEGIN
CALL NUMOUT(LINE1[0],NUM^BOTTLES,10,2);
CALL WRITE(MYTERM^NUM, LINE1, 30);
END;
END;
LINE1 ':=' "NO MORE BOTTLES OF BEER ON THE WALL !!";
CALL WRITE(MYTERM^NUM, LINE1, 37);
END;
<@comment>
TANGO (Witango) version of 99 bottles of beer.
Author: Wes Bramhall
</@comment>
<html>
<head>
<title>99 Bottles of Beer</title>
</head>
<body>
<@for start="1" stop="99">
<@calc expr="100-<@currow>"> bottle<@if
expr="<@currow>!= 99">s</@if> of beer on the wall,
<@calc expr="100-<@currow>"> bottle<@if
expr="<@currow>!= 99">s</@if> of beer.<br>
Take one down, pass it around,
<@if expr="<@currow>!=99">
<@calc expr="100-<@currow>-1"> bottle<@if
expr="<@currow>!= 98">s</@if> of beer on the wall.<br>
<@else>
0 bottles of beer on the wall.<br>
BUY MORE BEER!
</@if>
</@for>
</body>
</html>
# Tcl version of 99 bottles of beer on the wall
# Author: Don Libes (libes@nist.gov)
#
proc bottles {i} {
return "$i bottle[expr $i!=1?"s":""] of beer"
}
proc line123 {i} {
puts "[bottles $i] on the wall,"
puts "[bottles $i],"
puts "take one down, pass it around,"
}
proc line4 {i} {
puts "[bottles $i] on the wall.\n"
}
for {set i 99} {$i>0} {} {
line123 $i
incr i -1
line4 $i
}
// 99 bottles of beer - tdbengine version
// 03.06.2002 Horst Klier (www.klier.net)
procedure Main
var nBottles : Integer
var s : String
CgiCloseBuffer
nBottles:=99
while nBottles>=0
if nBottles=1
s:=''
else
s:='s'
end
CgiWriteLn(Str(nBottles)+' bottle'+s+' of beer on the wall,')
CgiWriteLn(Str(nBottles)+' bottle'+s+' of beer,')
if nBottles=0
CgiWriteLn('Go to the store, buy some more,')
CgiWriteLn('99 bottles of beer on the wall.')
else
CgiWriteLn('Take one down and pass it around,')
CgiWriteLn(Str(nBottles)+' bottle'+s+' of beer on the wall,')
end
nBottles--
end
endproc
! -- TECO version of 99 Bottles of beer
-- Hacked by Akira KIDA, <SDI00379@niftyserve.or.jp> !
hk@i#
qp-1"> qp:= ^A bottles^A '
qp-1"= qp:= ^A bottle^A '
qp"= ^ANo more bottles^A '
^A of beer^A
#hxbhk
@i#
qnup
qn<
mb ^A on the wall, ^A
mb ^A.
Take one down, pass it around.
^A
qp-1up
mb ^A on the wall.
^A
>#
hxmhk
99un
mmex^[^[
[% # 99 beers for the Template Toolkit (http://www.template-toolkit.org/)
# Author: David Mullen -%]
[%- BLOCK bottles -%]
[% beers or 'No' %] bottle[% beers == 1 ? '' : 's' %] of beer
[%- END -%]
[%- beers = 99; WHILE beers > 0 %]
<p>[% PROCESS bottles %] on the wall,<br />
[% PROCESS bottles %],<br />
You take one down, pass it around,<br />
[% beers = beers - 1; PROCESS bottles %] on the wall.</p>
[% END %]
; 1. Open Tera Term Pro (free VT100 emulator)
; 2. Control -> Macro
; 3. choose 99b.ttl
;
; it will run even if you close the app, to kill prematurely please open
; taskmanager and kill the ttpmacro.exe
;
; 99 Bottles of Beer macro for Tera Term
; by Lance Yamada
for i 99 1
j = i - 1
int2str istr i
int2str jstr j
strconcat istr ' bottles of beer on the wall,'
strconcat jstr ' bottles of beer on the wall!'
if i = 1 then
messagebox '1 bottle of beer on the wall,' 'Tera Term'
messagebox 'time to get more beer!' 'Tera Term'
else
messagebox istr 'Tera Term'
messagebox 'take one down pass it around,' 'Tera Term'
messagebox jstr 'Tera Term'
endif
next
\\\\\\\\
\ Beer \
\\\\\\\\
\
\ Program to print the lyrics to "99 Bottles of Beer on the Wall"
\ Runs under any version of DOS, 176 byte .COM file.
\
\ Written in TERSE by jim-neil@digital.net (Jim Neil). TERSE is
\ an x86 specific language that has the same level of control as
\ assembly, with the look-and-feel and ease-of-use of a HLL.
\
\ For more information on TERSE, visit the TERSE website at:
\ http://www.terse.com
main Group code,data;
Assume cs:main,ds:main;
O Equ <Offset main:>;
code Segment byte;
Org 0100h;
data Segment byte;
' m0 =" Bottle$";
' m1 =" of Beer on the Wall";
' nl =(10,13,'$');
' m2 =" of Beer", =(10,13);
' m3 ="Take one down and pass it around", =(10,13,'$');
data EndS;
Beer Proc;
cx = 99; \ cx = number to do.
{ \ for cx = 99..1, do...
dx = O(nl); ah = 9; !21h; \ new line.
al = cl; =.Bottles; \ print number and "Bottle(s)".
dx = O(m1); ah = 9; !21h; \ output lyric line 1.
al = cl; =.Bottles; \ print number and "Bottle(s)".
dx = O(m2); ah = 9; !21h; \ output lyric lines 2-3.
al = cl-; =.Bottles; \ print number - 1 and "Bottle(s)".
dx = O(m1); ah = 9; !21h; \ output lyric line 4.
}-.; \ loop till done...
!20h; \ return to DOS.
Beer EndP;
\\\\\\\\\\\
\ Bottles \
\\\\\\\\\\\
\
\ Bottles prints "n Bottle(s)", controling plural based on the
\ value of n passed in al.
\
\ Entry Conditions:
\ al = n.
\ ah = Scratch;
\ dx = Scratch;
\
\ Exit Conditions:
\ ax = scratch.
\ dx = scratch.
Bottles Proc;
=ax; =.BinDec; \ print number of beers.
dx = O(m0); ah = 9; !21h; \ output "bottle".
ax=; al - 1 ? <> \ if not 1...
{ dl = 's'; ah = 2; !21h; }; \ make it plural.
.=; \ and, return...
Bottles EndP;
\\\\\\\\\\
\ BinDec \
\\\\\\\\\\
\
\ BinDec prints a binary number (0-63h) in al to the screen
\ in decimal with leading zero supression.
\
\ Entry Conditions:
\ ah = scratch.
\ al = number to convert.
\ dx = scratch.
\
\ Exit Conditions:
\ ax = scratch.
\ dx = scratch.
BinDec Proc Near;
"*; ax + '00'; dh = al; \ split and convert, dh = save LSB.
ah - '0' ? <> \ if MSB is non-zero...
{ dl = ah; ah = 2; !21h; }; \ then, output MSB.
dl = dh; ah = 2; !21h; \ output LSB.
.=; \ and return...
BinDec EndP;
code EndS;
End Beer;
%% TeX/LaTeX version of 99 bottles of Beer
%%
%% Craig J Copi - copi@oddjob.uchicago.edu
%%
\parindent=0pt
\newcount\beercurr
\def\beer#1{\beercurr=#1\let\next=\removebeer\removebeer}
\def\removebeer{
\ifnum\beercurr>1
\the\beercurr\ bottles of beer on the wall,\par
\the\beercurr\ bottles of beer,\par
take one down, pass it around,\par
\advance\beercurr by -1
\the\beercurr\ bottle\ifnum1<\beercurr{s}\fi\ of beer on the wall.\par
\vskip 2ex\relax
\else
1 bottle of beer on the wall,\par 1 bottle of beer,\par
take one down, pass it around,\par no bottles of beer on the wall.\par
\vskip .5ex
Time to buy some more beer\ldots. \let\next=\relax
\fi
\next}
\beer{99}
\input texinfo @c -*-texinfo-*-
@c texinfo version of 99 bottles of beer
@c Laurent Vogel, http://lvogel.free.fr
@c run as: makeinfo --no-headers -o - THIS_FILE
@macro e @end macro
@macro p{c} @value{i} bottle@value{s} of beer\c\
@end macro
@set i 99
@set s s
@macro a{i,s}
@noindent @p{@e on the wall\\,}@*@p{.}@*@set s \s\
Take one down, pass it around,@*@set i \i\
@p{@e on the wall.}@sp 1
@end macro
@macro l{i} @a{\i\,s}
@end macro
@macro m{a}
@l{\a\8}@l{\a\7}@l{\a\6}@l{\a\5}@l{\a\4}@l{\a\3}@l{\a\2}
@end macro
@macro n{a} @l{\a\9}@m{\a\}@l{\a\1}@l{\a\0}
@end macro
@m{9}@l{91}@l{90}
@n{8}@n{7}@n{6}@n{5}@n{4}@n{3}@n{2}@n{1}
@l{9}@m{}@a{1,}@a{No,}
@bye
TI-81 Logic
By Jon Neal 1997
:99>X
:0>Y
:LBL 1
:IF X=1
:GOTO 2
:DISP X
:DISP "BOTTLES OF BEER ON THE WALL"
:DISP X
:DISP "BOTTLES OF BEER"
:DISP "TAKE ONE DOWN"
:DISP "PASS IT AROUND"
:X-1>X
:LBL 4
:Y+1>Y
:IF Y=500
:GOTO 3
:GOTO 4
:LBL 3
:GOTO 1
:LBL 2
:DISP X
:DISP "BOTTLE OF BEER ON THE WALL"
:DISP X
:DISP "BOTTLES OF BEER"
:DISP "NO BOTTLES OF BEER ON THE WALL"
:DISP "NO BOTTLES OF BEER"
:DISP "GO TO THE STORE"
:DISP "AND BUY SOME MORE"
:END
: TI-85 Printing calculator version of 99 Bottles of Beer
PROGRAM:BEER
:100-->A
:2-->B
:"Bottles of Beer"-->BOTTLES
:"One Bottle of Beer"-->ONE
:"On the Wall"-->ON
:"Take one down"-->TAKE
:"And pass it around."-->PASS
:"Zero Bottles of Beer"-->ZERO
:"Go to the store and "-->STORE
:"Buy some more."-->BUY
:Lbl LOOP
:ClLCD
:Outpt(1,1,A)
:Outpt(1,5,BOTTLES)
:Outpt(2,1,ON)
:Outpt(3,1,A)
:Outpt(3,5,BOTTLES)
:Outpt(4,1,TAKE)
:Outpt(5,1,PASS)
:Outpt(6,1,A-1)
:Outpt(6,5,BOTTLES)
:DS<(A,F)
:Pause
:Goto LOOP
:ClLCD
:Outpt(1,1,ONE)
:Outpt(2,1,ON)
:Outpt(3,5,ONE)
:Outpt(4,1,TAKE)
:Outpt(5,1,PASS)
:Outpt(6,1,ZERO)
:Pause
:ClLCD
:Outpt(1,1,STORE)
:Outpt(2,1,BUY)
:Disp ""
:Disp "Hit ENTER to buy more."
<~null~ Tilton version of 99 bottles of beer,
~ Laurent Vogel, http://lvogel.free.fr
~ (Tilton info at http://www.crockford.com/index.html)
~><~set~b~ bottle~><~set~t~Take one down, pass it around,
~><~set~o~ of beer~><~set~w~ on the wall~>99<~b~>s<~o~><~w~>,
99<~b~>s<~o~>.<~set~i~98~><~define~s~<~gt?~<~i~>~1~s~>~><~set~n~
~><~n~><~t~><~define~p~<~i~><~b~><~s~><~o~><~w~>.<~n~>
<~i~><~b~><~s~><~o~><~w~>,<~n~><~i~><~b~><~s~><~o~>.
<~t~>~><~loop~<~s~>~<~p~><~set~i~<~sub~<~i~>~1~>~>~><~p~>No<~b~><~o~><~w~>.
%: 99 Bottles of Beer in TINCL. '98 Ben Olmstead.
TINCL is meant for writing CGI programs, and, though it is possible
to write command-line utilities in TINCL, this version *is* meant to
be run on the web. You can check out a sample form at
<http://www.students.mines.edu/students/b/bolmstea/beer.html> :%
%.config.%
get-input, post-input
%{
#include <stdlib.h>
int beer;
}%
%.fragments.%
<p>
%#beer#% bottle%{ if ( beer != 1 ) { }%s%{ } }% of beer on the wall,<br>
%#beer#% bottle%{ if ( beer != 1 ) { }%s%{ } }% of beer,<br>
Take one down and pass it around,<br>
%{ if ( !--beer ) { }%No more%{ } else { }%%#beer#%%{ } }% bottle%{ if ( beer != 1 ) { }%s%{ } }% of beer on the wall.
</p>
%.html.%
%{ set_var( &beer, 0, 1000, 99, get_value( "beer" ) ); }%
<html><head><title>%#beer#% Bottles of Beer on the Wall</title></head>
<body>
%{ while( beer > 0 ) { %(fragment)% } }%
</body></html>
#nop 99 Bottles of beer for TinTin++ (Mud Client)
#nop Coded 1997, Andrew Forster <bluemeat@mono.org>
#var {do} {#showme}
#nop (can use say if you want to sing to the mud :-) )
#alias {beer %0} {#math {wang} {%%0-1}; $do %0 bottles of beer on the
wall; $do %0 bottles of beer; $do take one down, pass it around,;
beerloop; nobeer;}
#nop The initial part of the beer call
#alias {beerloop} {bl $wang}
#nop a weird way of doing it, but the only way I can see of getting the
#nop maths to propagate into the beer statement.
#alias {bl %0} {#loop {%%0, 2} {$do %0 bottles of beer on the wall; $do
-------; $do %0 bottles of beer on the wall; $do %0 bottles of beer; $do
take one down, pass it around; $do one bottle of beer on the wall}}
#nop The main loop of the beer passing
#alias {nobeer} {$do --------; $do one bottle of beer on the wall; $do
one bottle of beer; $do take one down pass it around; $do fuck me
there's no beer left; }
#nop No beer left. So give up :-)
// TMMLPTEALPAITAFNFAL version of 99 Bottles of beer
// "The Multi-Million Language Project To End All Language
// Projects And Isn't That A Fine Name For A Language"
// Philipp Winterberg, http://www.winterbergs.de
//
// How to use:
// 1. Install TMMLPTEALPAITAFNFAL (http://www.p-nand-q.com/t.htm)
// 2. Set system date to 2002.06.28 (important!!!)
// 3. Run and enjoy ;)
//
DECLARE CELL 100 AS READPOS
DECLARE CELL 99 AS B
DECLARE 10 AS NEWLINE
DECLARE 0 AS ZERO
WRITE CHAR NEWLINE
COPY 99 TO B
WRITE INTEGER B
WHILE B > ZERO DO GOSUB 100
STOP
LINE 100: COPY "bottle(s) of beer on the wall," TO CELL 0
COPY 0 TO READPOS
WRITE INTEGER B
WHILE READPOS INDIRECT DO GOSUB 200
WRITE CHAR NEWLINE
WRITE INTEGER B
COPY "bottle(s) of beer. " TO CELL 0
COPY 0 TO READPOS
WHILE READPOS INDIRECT DO GOSUB 200
WRITE CHAR NEWLINE
COPY "Take one down, pass it around," TO CELL 0
COPY 0 TO READPOS
WHILE READPOS INDIRECT DO GOSUB 200
WRITE CHAR NEWLINE
COPY "bottle(s) of beer on the wall." TO CELL 0
COPY 0 TO READPOS
SUB 1 FROM B
WRITE INTEGER B
WHILE READPOS INDIRECT DO GOSUB 200
WRITE CHAR NEWLINE
WRITE CHAR NEWLINE
RETURN
LINE 200: WRITE CHAR READPOS INDIRECT
ADD 1 TO READPOS
RETURN
* Tokiwa version of 99 Bottles of beer (Bottles.bas)
* See http://www.terra.es/personal/oxigeno2/BASIC.es/compiladores_basic.htm
* Philipp Winterberg, http://www.winterbergs.de
call bottles(1," bottle(s) of beer"," on the wall")
subroutine bottles(b,a$,c$)
integer b
if b<100 then
call bottles(b+1,a$,c$)
print b; a$; c$; ","
print b; a$; "."
print "Take one down, pass it around,"
print b-1; a$; c$; "."; chr$(13); chr$(10)
endif
return
subend
end
<copyright> 99 bottles of beer on the wall in TOM.
By <a href="mailto:jjens@primenet.com">John Jensen</a>
No Copyright, this code is placed in the public domain.
</copyright>
implementation class beer
<doc> Every program needs a main. </doc>
int
main Array arguments
{
int beers;
beers = 99;
while (beers > 0) {
[[[stdio out] print beers] print " bottles of beer on the wall, "];
[[[stdio out] print beers] print " bottles of beer.\n"];
[[stdio out] print "Take one down, pass it around, "];
beers--;
if (beers != 0) {
[[[stdio out] print beers] print " bottles of beer on the wall.\n\n"];
} else {
[[stdio out] print "no more bottles of beer on the wall.\n\n"];
}
}
= 0;
}
end;
implementation instance beer end;
#(#*( TRAC version of 99 bottles of beer. ))
#(#*( written by Akira KIDA, SDI00379@niftyserve.or.jp ))
#(#*( ))
#(#*( To run this, save the entire script as `beer.trac', and then ))
#(#*( type three lines in order. ))
#(#*( ))
#(#*( #(ld,beer.trac) ))
#(#*( #(cl,beer,99) ))
#(#*( ' ))
#(#*( ))
#(ds,bottle,(#(gr,1,B,(No more bottles),(#(gr,2,B,(B bottle),(B bottles))))))
#(ss,bottle,B)
#(ds,beer,(#(gr,1,B,,
(#(ps,#(cl,bottle,B) of beer on the wall(,) #(cl,bottle,B) of beer.(
)Take one down(,) pass it around.(
)#(cl,bottle,##(-,B,1)) of beer on the wall.(
)(
))#(cl,beer,##(-,B,1))))))
#(ss,beer,B)
/* Microsoft Transact-SQL version of the beer song
** Joseph Thoennes, thoennes@paranet.com
*/
set nocount on
create table #beer (bottle tinyint identity)
while (select isnull(max(bottle),0) from #beer) < 99 insert into #beer
default values
select ltrim(str(bottle)) + ' bottle' + case when bottle > 1 then 's' end
+ ' of beer on the wall, '
+ ltrim(str(bottle)) + ' bottle' + case when bottle > 1 then 's' end + '
of beer, take '
+ case when bottle > 1 then 'one' else 'it' end + ' down, pass it around,
'
+ case when bottle - 1 > 0 then ltrim(str(bottle - 1)) else 'no more' end
+ ' bottle' + case when bottle - 1 <> 1 then 's' end + ' of beer on the
wall.'
from #beer order by bottle desc
drop table #beer
{
/* pl/TRIM (http://www.trifox.com)
Author: Henrik Nilsson (he_ni@hotmail.com) */
int b = 99;
while (b >= 1)
{
printf(b ^^ decode(b, 1, " bottle", " bottles") ^^ " of beer on the wall,");
printf(b ^^ decode(b, 1, " bottle", " bottles") ^^ " of beer.");
printf("Take one down, pass it around,");
b--;
if (b > 0)
printf(b ^^ decode(b, 1, " bottle", " bottles") ^^ " of beer on the wall.");
else
printf("No more bottles of beer on the wall.");
printf("");
}
}
.\"
.\" 99 bottles of beer.
.\" [ntg]roff macro
.\" Jaap Akkerhuis
.\"
.if n .pl 1
.nr b 99 1
.nf
.ds b "of beer
.ds s, " \*b on the wall,
.ds t take one down, pass it around,
.ds s. " \*b on the wall.
.ds B " bottles
.de BB
.if \\nb=1 .rn BB xx
\\nb\\*B\\*(s, \\nb\\*B \\*b,
\\*t
.if \\n-b=1 .ds B " bottle
.if \\nb \\nb\\*B\\*(s.
.BB
..
.BB
no more\*Bs\*(s.
true version of 99 bottles of beer
Laurent Vogel http://lvogel.free.fr
[,$.][,"No more".]["s".][$0=$7<?~7<?" bottle".$1=~5<?" of beer".]
[" on the wall".][".".,]99[$0>]
[3<!2<!",".3<!1<!"Take one down, pass it around,".1-3<!2<!1<!]#
! True Basic version of 99 Bottles of beer (Bottles.tru)
! See http://truebasic.com/tbv5.html
! Philipp Winterberg, http://www.winterbergs.de
FOR b = 99 TO 1 STEP -1
PRINT b;" bottle(s) of beer on the wall,"
PRINT b;" bottle(s) of beer."
PRINT "Take one down, pass it around,"
PRINT b-1;" bottle(s) of beer on the wall."
PRINT " "
NEXT b
END
# 99 Bottles of Beer on the Wall
# Written by Andrew Turley aturley@sound.net
$para = " bottle"
$parb = " of beer on the wall,"
$parc = " of beer."
$pard = "Take one down, pass it around,"
$pare = " of beer on the wall."
$parf = "no bottles of beer on the wall!"
$pl = "s"
%beer = 99
repeat
display %beer
display $para
if ! %beer = 1
display $pl
end
display $parb\n
display %beer
display $para
if ! %beer = 1
display $pl
end
display $parc\n
display $pard\n
%beer = %beer - 1
if %beer > 0
display %beer
display $para
if %beer > 1
display $pl
end
display $pare\n
end
if %beer = 0
display $parf\n
end
display \n
until %beer = 0
/****************************************************************
A TSE Pro editor macro that implements the beer song.
Sammy Mitchell, Dec 9, 1998 www.semware.com
****************************************************************/
// return "n bottles", "1 bottle", or "no more..." based on num_bottles
string proc bottles(integer num_bottles)
case num_bottles
when 0 return ("no more bottles of beer")
when 1 return ("1 bottle of beer")
endcase
return (Str(num_bottles) + " bottles of beer")
end
// display the verses
proc Sing()
integer num_bottles
for num_bottles = 99 downto 1
WriteLine(bottles(num_bottles); "on the wall,")
WriteLine(bottles(num_bottles), ".")
WriteLine("You take one down, pass it around,")
WriteLine(bottles(num_bottles - 1); "on the wall.")
WriteLine("")
endfor
end
// display the beer song in a pop-up window
proc main()
if PopWinOpen(1, 1, 40, Query(ScreenRows),
1, "Sing along...", Color(Bright Yellow on Blue))
Set(Attr, Color(Bright Yellow on Blue))
ClrScr()
Sing()
WriteLine("")
WriteLine("Press a key...")
GetKey()
PopWinClose()
endif
end
Singing '99 bottles of beer on the wall' With a Telemecanique TSX-17 PLC
(Programmable Logic Controller)
This is a condensed listing of a PL7-2 TSX-17 PLC Program for printing the
Lyrics to everybody's favorite beer bottle song. This program is written
to send the lyrics out of the terminal port of the TSX-17 PLC, using the
terminal type text block. It is presumed that some sort fo serial device
would be attached to this terminal port, that the terminal port is in its
ASCII mode, and that the external device is set for the TSX-17 PLC's default
communication parameters of 9600 baud, 8 data bits, one stop bit, Odd parity.
Both the Ladder Logic and GRAFCET languages available in the TSX-17 PLC are
used.
It should be noted that PLCs in general are not well suited to this type of
application, being designed instead for real time control of machinery.
Theory Of Operation:
The code is commented below, however, here are some general comments on how
this works. A TSX 17-PLC, like all PLCs, continuously scans it's programs
logic. It will update it's Input information to an internal buffer, execute
the program in the PLC, Write the output information from an internal buffer
to the real-world I/O, and then go back and update the inputs. The TSX-17's
scan, unlike many other PLC models, is divided into three parts. The first
portion may be programmed in Ladder Logic, and is used here to capture the
'Start' input, which, when turned on, starts the serial transmission of the
data involved.
The next portion of the program is written in GRAFCET, a precursor to the
IEC1131-3 SFC language. In this language, each 'box' represents a step, or
action, and each 'cross' represents a condition that needs to become true in
order to advance to the next step. The actual code inside these Steps and
Transitions is here written in Ladder Logic. The GRAFCET chart here is used to
co-ordinate the activity of the Send Line and Send CRLF Text Blocks, to keep
the data to be sent updated, and to determine when the song lyrics are complete.
The final portion of the program, known as the POST-PROCESSING portion, is
again written in Ladder Logic. In this program, the Text Block structures that
control serial communications to/from the TSX-17 are placed here, with their
controlling logic. Decrementing of the number of bottles occurs here as well.
It should be noted that the TSX-17 PLC's Text Block may send a maximum of 30
bytes at a time. Fortuitously, the phrase '99 Bottles of beer on the wall'
contains precisely 30 characters. This made it necessary to use some other
mechanism to transmit the required CRLF's - hence the need for TXT1.
Templates for the Data to be sent over the serial line are held in the TSX-17
PLC's Constant Word Memory. These are transferred to the transmit buffers of
the text blocks as required by program in the GRAFCET chart.
CONSTANT WORD MEMORY CONFIGURATION:
This is the CONSTANT WORD configuration, where the strings to send to the
terminal port are stored. Constant Words 0 through 13 contain the string:
" BOTTLES OF BEER ON THE WALL",
Constant words 15 through 29 contain:
"TAKE ONE DOWN, PASS IT AROUND"
and Constant Word 35 contains a CRLF pair. These were, of course, entered in
hexadecimal.
+------------------------**** CW 0 -> CW 63 ****------------------------+
| -----------DECIMAL----------- ----------HEXA--------- --MESSAGE-- |
| --0-- --1-- --2-- --3-- --0- --1- --2- --3- 0 1 2 3 |
| |
|CW 0 : 16928 21583 19540 21317 4220 544F 4C54 5345 B OT TL ES |
|CW 4 : 20256 8262 17730 21061 4F20 2046 4542 5245 O F BE ER |
|CW 8 : 20256 8270 18516 8261 4F20 204E 4854 2045 O N TH E |
|CW 12 : 16727 19532 0 16724 4157 4C4C 0000 4154 WA LL .. TA |
|CW 16 : 17739 20256 17742 17440 454B 4F20 454E 4420 KE O NE D |
|CW 20 : 22351 11342 20512 21313 574F 2C4E 5020 5341 OW N, P AS |
|CW 24 : 8275 21577 16672 20306 2053 5449 4120 4F52 S IT A RO |
|CW 28 : 20053 68 0 0 4E55 0044 0000 0000 UN D. .. .. |
|CW 32 : 0 0 0 2573 0000 0000 0000 0A0D .. .. .. .. |
|CW 36 : 0 0 0 0 0000 0000 0000 0000 .. .. .. .. |
|CW 40 : 0 0 0 0 0000 0000 0000 0000 .. .. .. .. |
|CW 44 : 0 0 0 0 0000 0000 0000 0000 .. .. .. .. |
|CW 48 : 0 0 0 0 0000 0000 0000 0000 .. .. .. .. |
|CW 52 : 0 0 0 0 0000 0000 0000 0000 .. .. .. .. |
|CW 56 : 0 0 0 0 0000 0000 0000 0000 .. .. .. .. |
|CW 60 : 0 0 0 0 0000 0000 0000 0000 .. .. .. .. |
+------------------------------------------------------------------------------+
PREPROCESSING SECTION:
This section consists of a single line of Ladder Logic. Here, the internal
bit B0 is set (and will remain set) when the system sees Input 0,0 transition
from an off state to an on state.
** LABEL 10 Start Condition
I0,0 B1 B0
|--| |--+--|/|-------------------------------------------------------------(S)-|
| | |
| | |
| | B1 |
| +------------------------------------------------------------------( )-|
SEQUENTIAL SECTION - THE GRAFCET CHART:
Here is the Grafcet Chart for this program. The initial step, Step 0, waits
until the internal bit B0 mentioned above has been set, and then starts the
process. Steps 1,3,5,and 7 load data from tables in Constant Word memory to
the transmission table of TXT0, the Send line Text Block. The CRLF Text Block,
as we will see in the Post-Processing section, also fires upon activation of these
steps, as well as steps 9 and 11. Steps 2,4,6,and 8 cause the Send Line Text block
to fire. All of these steps transition to the next step upon completion of the
sending process of their associated Text Block, using internal bits B2 (for TXT0,
the Send Line Text Block) and B4 (For TXT1, the CRLF Text Block) as flags.
The ALternative sequence under Step 11 returns control to Step 0 upon completion
of the sequence, otherwise, control is returned to Step 1, and the next bottle's
lyrics are transmitted.
---+------+------+------+------+------+------+------+------+-------------------
V 11 V 5 |
| | |
| | |
.-. .-. |
|#| 0 | | 6 |
`_' `_' |
| | |
| | |
-+- -+- |
| V 11 | |
|------' | |
.-. .-. |
| | 1 | | 7 |
`_' `_' |
| | |
| | |
-+- -+- |
| | |
| | |
.-. .-. |
| | 2 | | 8 |
`_' `_' |
| | |
| | |
-+- -+- |
| | |
| | |
.-. .-. |
| | 3 | | 9 |
`_' `_' |
| | |
| | |
-+- -+- |
| | |
| | |
.-. .-. |
| | 4 | | 10 |
`_' `_' |
| | |
| | |
-+- -+- |
| | |
| | |
.-. .-. |
| | 5 | | 11 |
`_' `_' |
| |------. |
| | | |
-+- -+- -+- |
| | | |
| | | |
| | | |
V 6 V 0 V 1 |
|
SEQUENTIAL SECTION: CODE ASSOCIATED WITH STEPS AND TRANSITIONS
Step 0: Set TXT0 to send 30 characters, set bottles to 99.
** X0 Init bottles
+------OPERATE-------+
|-------------------------------------------------------+|99 -> W0 ||
| |+--------------------+|
| | |
| |+------OPERATE-------+|
| +|30 -> TXT0,L ||
| +--------------------+|
X6: send Line 3
** X6
Transition upon seeing B0 on.
** X0 --> X1 Start condition
B0
|--| |---------------------------------------------------------------------(#)-|
After line 3 sent, wait till TXT0 done.
** X6 --> X7
B2
|--| |---------------------------------------------------------------------(#)-|
X1: Load Line 1 info. Convert Bottle number (in W0) to ASCII, write as 6 chars
with leading zeros to W8, thus ensuring W10 contains the last two chars.
Copy Line 1 info to the remainder of TXT0's transmit table.
** X1 Load Line 1
+------OPERATE-------+
|-------------------------------------------------------+|BTA W0 -> W8 ||
| |+--------------------+|
| | |
| |+------OPERATE-------+|
| ||CW0[14] -> W11[14] ||
| |+--------------------+|
| | |
| | B0 |
| +------------------(R)-|
X7: Similar to above for Line 4 - handle special case of NO Bottles (Hex 6f4e
is 'NO')
** X7
+------OPERATE-------+
|-------------------------------------------------------+|BTA W0 -> W8 ||
| |+--------------------+|
| | |
| |+------OPERATE-------+|
| +|CW0[14] -> W11[14] ||
| +--------------------+|
| |
|+---COMPAR----+ +------OPERATE-------+|
||W0 <= 0 |-----------------------------------------|H'6F4E' -> W10 ||
|+-------------+ +--------------------+|
When CRLF TXT block is done, continue
** X1 --> X2
B4
|--| |---------------------------------------------------------------------(#)-|
** X7 --> X8
B4
|--| |---------------------------------------------------------------------(#)-|
** X2
** X8
** X2 --> X3
B4
|--| |---------------------------------------------------------------------(#)-|
** X8 --> X9
B2
|--| |---------------------------------------------------------------------(#)-|
X3: Line 2 is like Line 1, but shorter - send same thing, only fewer bytes.
** X3
+------OPERATE-------+
|--------------------------------------------------------|18 -> TXT0,L ||
| +--------------------+|
** X9
** X3 --> X4 b2
B2
|--| |---------------------------------------------------------------------(#)-|
** X9 --> X10
B4
|--| |---------------------------------------------------------------------(#)-|
** X4
** X10
** X4 --> X5
B4
|--| |---------------------------------------------------------------------(#)-|
** X10 --> X11
|--------------------------------------------------------------------------(#)-|
X5: Load "Take one down, etc line". Set Transmit length back to 30 chars.
** X5
+------OPERATE-------+
|-------------------------------------------------------+|CW15[15] -> W10[15]||
| |+--------------------+|
| | |
| |+------OPERATE-------+|
| +|30 -> TXT0,L ||
| +--------------------+|
** X11
** X5 --> X6
B4
|--| |---------------------------------------------------------------------(#)-|
** X11 --> X0
B4 +---COMPAR----+
|--| |---|W0 <= 0 |---------------------------------------------------(#)-|
| +-------------+ |
** X11 --> X1
B4 +---COMPAR----+
|--| |---|W0 > 0 |---------------------------------------------------(#)-|
| +-------------+ |
POST PROCESSING SECTION:
10: The SEND LINE INFO TEXT BLOCK. When Steps 2,4,6, or 8 are activated (shown
by X2, X4, X6, and X8 respectively) Send the contents of Words W10 through W25
to the terminal port. Upon completion, set B2 for a single PLC scan.
** LABEL 10 Line Text Block
X2 R+--TXT0---+D B3 B2
|--| |--+ --| |----------+--|/|-----------------------------( )-|
| | | | | |
| | | | | |
| X4 | S|TER |E | B3 |
|--| |--+-------+--| |-- +----------------------------------( )-|
| | | |LOCAL | |
| | | | | |
| X6 | | O| | |
|--| |--| +--|W10 | |
| | | | |
| | |T,L: 30 | |
| X8 | I|T,S: | |
|--| |--+ --| | |
+---------+
20: The SEND CRLF Text Block.
Upon activation of steps 1,3,5,7,9, or 11, send the contents of CW35 to the
terminal port. Set B4 for a single PLC scan upon completion.
** LABEL 20 CRLF Text Block
X1 R+--TXT1---+D B5 B4
|--| |--+---------------+ --| |----------+--| |-------------( )-|
| | | | | | |
| | | | | | |
| X3 | X7 | S|TER |E | B5 |
|--| |--| +--| |--+-------+--| |-- +------------------( )-|
| | | | | |LOCAL | |
| | | | | | | |
| X5 | | X9 | | O| | |
|--| |--+ |--| |--| +--|CW35 | |
| | | | | |
| | | |T,L: 2 | |
| | X11 | I|T,S: | |
|---------------+--| |--+ --| | |
+---------+
If X7 is active, decrement the Bottles number stored in W0.
** LABEL 30
X7 B7 +------OPERATE-------+
|--| |--+--|/|-------------------------------------------|W0 - 1 -> W0 ||
| | +--------------------+|
| | |
| | B7 |
| +------------------------------------------------------------------( )-|
That's it. Space does not permit a complete explanation of how Ladder Logic and
GRAFCET work and interact in PLCs, but I hope you caught the gist of the program.
/* Turbo C version of 99 Bottles of beer (Bottles.c) */
/* See http://community.borland.com/article/0,1410,20841,00.html */
/* Philipp Winterberg, http://www.winterbergs.de */
#include <stdio.h>
int b;
main() {
for (b = 99; b > 0; b--)
printf("%d bottle(s) of beer on the wall,\n%d %s\n%s\n%d %s", b, b,
"bottle(s) of beer.", "Take one down, pass it around,", (b-1),
"bottle(s) of beer on the wall.\n\n");
}
{ Turbo Pascal for Windows version of 99 Bottles of beer (Bottles.pas) }
{ Philipp Winterberg, http://www.winterbergs.de }
program Bottles;
uses wincrt;
var b: byte;
function plural(anz_flaschen: byte): string;
begin
if anz_flaschen <> 1
then plural:= 's'
else plural:= ''
end; {plural}
begin
screensize.y:= 1 + 99 * 5;
inactivetitle:= ' 99 Bottles of beer ';
initwincrt;
for b:=99 downto 1 do
begin
writeln(b :2, ' bottle' + plural(b) + ' of beer on the wall, ');
writeln(b :2, ' bottle' + plural(b) + ' of beer.');
writeln('Take one down, pass it around,');
writeln((b-1) :2, ' bottle' + plural(b-1) + ' of beer on the wall.');
writeln
end
end. {Bottles}
{ Turbo Pascal version of 99 Bottles of beer (Bottles.pas) }
{ Philipp Winterberg, http://www.winterbergs.de }
program Bottles;
var b: byte;
function plural(anz_flaschen: byte): string;
begin
if anz_flaschen <> 1
then plural:= 's'
else plural:= ''
end; {plural}
begin
b:= 99;
repeat
writeln(b, ' bottle' + plural(b) + ' of beer on the wall, ');
writeln(b, ' bottle' + plural(b) + ' of beer.');
writeln('Take one down, pass it around,');
writeln((b-1), ' bottle' + plural(b-1) + ' of beer on the wall.');
dec(b)
until b = 0;
readln;
end. {Bottles}
> Turbo PL version of 99 Bottles of beer (Bottles.tmc)
> See http://www.jmksf.de/turbo.html
> Philipp Winterberg, http://www.winterbergs.de
Clear.
Declare %b%.
Set %b%='99'.
Loop %b%>'1'.
Pout %b%:
Pout " bottle(s) of beer on the wall,".
Pout %b%:
Pout " bottle(s) of beer.".
Pout "Take one down, pass it around,".
%Calc %b%-'1'.
Pout %b%:
Pout " bottle(s) of beer on the wall.".
Pout "".
Endloop.
Sec '1'.
% Ric Holt holt@csri.toronto.edu
% Turing language version of 99 bottles of beer
for decreasing i : 99 .. 1
put i, " bottle(s) of beer on the wall, ", i, " bottle(s) of beer"
put "Take one down, pass it around, ", i - 1,
" bottle(s) of beer on the wall"
end for
*--- Chris Lopez - lopez@huey.vp.uiuc.edu ---*
*--- start of code ---*
define
maxbeer = 99
origin:n1
beer $$ # of beers remaining
atloc $$ where to start writing this line
nextlin(x) = (x <= (x+100) $mod$ 3200)
*
mode rewrite
calc beer <= maxbeer
atloc <= 1
loop
. at nextlin(atloc)
. showt beer,2
. * Warning: trailing space on following line
. write bottles of beer on the wall,
. showt beer,2
. write bottles of beer.
. at nextlin(atloc)
. write Take one down, pass it around.
outloop ((beer<=beer-1) < 2)
. showt beer-1,2
. write bottles of beer.
endloop
*
write 1 bottle of beer.
at nextlin(atloc)
write 1 Bottle of beer on the wall, 1 bottle of beer.
Take it down, pass it around, no bottles of beer on the wall.
*
pause keys=all
jumpout q
*--- end of code ---*