99 bottles of beer: Difference between revisions

From Rosetta Code
Content added Content deleted
(added common lisp example)
m (Shortened some lines for smaller screens)
Line 54: Line 54:
int main(int argc, char* argv[]){
int main(int argc, char* argv[]){
for(int x = 99;x>=1; --x){
for(int x = 99;x>=1; --x){
cout<<x<<"bottles of beer on the wall\n"<<x<<"bottles of beer\n"<<"Take one down, pass it around\n"<<x-1<<"bottles of beer on the wall\n\n";
cout<<x<<"bottles of beer on the wall\n"<<x<<"bottles of beer\n";
cout<<"Take one down, pass it around\n"<<x-1<<"bottles of beer on the wall\n\n";
}
}
}</c>
}</c>
Line 240: Line 241:
--x;
--x;
JOptionPane.showMessageDialog(null, x + " bottles of beer on the wall");//show a popup message
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 area
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
if(x == 0){//if it's the end

Revision as of 06:53, 1 March 2008

99 bottles of beer is a programming puzzle. It lays out a problem which Rosetta Code users are encouraged to solve, using languages and techniques they know. Multiple approaches are not discouraged, so long as the puzzle guidelines are followed. For other Puzzles, see Category:Puzzles.

In this puzzle, 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/

Ada

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

BASIC

Works with: QuickBasic version 4.5

Sound

This version plays the tune 100 times while printing out the number of beers on the wall. <qbasic>PLAY "<" FOR i = 100 TO 1 STEP -1

       PRINT i - 1
       PLAY "e-8e-8e-8<b8b8b8>e-8e-8e-8e-4"
       PLAY "f8f8f8c8c8c8f4"
       PLAY "d4d8d8 N0 d8d8d8d4"
       PLAY "<a+8a+8a+8>c8c8d8d+8d+8d+8d+4"

NEXT i</qbasic>

Text

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

C++

<c>#include<stdio> using namespace std; int main(int argc, char* argv[]){

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

}</c>

Common Lisp

<lisp>(defun bottles (x)

   (if (>= x 0)
    (progn
      (format t "~a bottles of beer on the wall~%" x)
      (if (not (equal x 0))

(progn (format t "~a bottles of beer~%" x) (format t "Take one down, pass it around,~%") (bottles (- x 1)))))))</lisp>

and then just call

<lisp>(bottles 99)</lisp>

D

Uses a non-commutative operator to construct a narrative expression of 99-bottles song. <d>module nbottles ; import std.string ; import std.stdio ;

alias Exception NoMoreBottlesLeft  ;

enum { // role

 None    = 0x0, // normal for OP and Term 
 Taker   = 0x1, // for OP that minus one bottlesLeft
 Viewer  = 0x2, // for Term display bottlesLeft
 NewLine = 0x4, // for Term that sending a newline to IO

} class XP {

 static string[] ones = ["","one","two","three","four",
                         "five","six","seven","eight","nine"] ;
 static string[] tens = ["", "ten", "twenty","thirty","fourty",
                         "fifty","sixty","seventy","eighty","ninty"] ;
 static string[] teens = ["","eleven","twelve","thirteen","fourteen",
                          "fifteen","sixteen","seventeen","eighteen","nineteen"] ;
 static private int bottlesLeft = 99 ;
 static bool opCall() {
   if (bottlesLeft == 0)
     throw new NoMoreBottlesLeft("") ;
   return true ;
 }
 static string Cap(string s) {
   return toupper(s[0..1]) ~ s[1..$] ;
 }
 static string num2word(int i) {
   if (i == 0)
     return "No more" ;
 //return std.string.toString(i) ;
   string[2] digits ;    
   int numTen = i / 10 ;   
   int numOne = i % 10 ;
   if(i == 10) 
     digits[1] = tens[1] ;      
   else if(numTen == 0)
     digits[1] = ones[numOne] ;
   else if(numTen == 1)
     digits[1] = teens[numOne] ;
   else {
     digits[0] = tens[numTen] ;
     digits[1] = ones[numOne] ;
   }     
   return Cap(strip(join(digits," "))) ;
 }
 static string getBottles() {
   string num = num2word(bottlesLeft) ;
   string pural = (bottlesLeft != 1) ? "s" : "";
   return num ~ " bottle" ~ pural ;
 }
 string words ;
 int role ;
 this (string w, int r) { words = w, role = r ; }
 string getWord() {
   string postfix = " ";
   string word ;
   if (words is null)
     return "" ;
   else
     word = words ;
   if (role & Viewer)
     word = getBottles ;
   if (role & NewLine)
     postfix = "\n" ;
   return word ~ postfix ;
 }

} alias XP A_drunker_sings_a_song ;

class Term : XP {

 this (string w = null, int r = None) { super(w, r) ; }

} class OP : XP {

 this (string w = null, int r = None) { super(w, r) ; }
 OP opDiv_r(Term t) {
   if(role & Taker)
     A_drunker_sings_a_song.bottlesLeft-- ;
   writef(t.getWord) ;
   writef(getWord) ;
   return this ;         
 }
 Term opDiv(Term t) {
   writef(t.getWord) ;
   return new Term ;
 }

}

void main() {

 Term N_bottles = new Term("", Viewer) ;
 OP of = new OP("of") ;
 Term beer = new Term("beer") ;
 OP on = new OP("on") ;
 Term the_wall = new Term("the wall", NewLine) ;
 Term beer_ = new Term("beer", NewLine) ;
 Term Take = new Term("Take") ;
 OP one = new OP("one", Taker) ;
 Term down = new Term("down,") ;
 Term pass = new Term("pass") ;
 OP it = new OP("it") ;
 Term around = new Term("around", NewLine) ;
 Term the_wall_ = new Term("the wall\n", NewLine) ;
 
 try{
   for(; A_drunker_sings_a_song();
 
     N_bottles/of/beer/on/the_wall,
     N_bottles/of/beer_ ,
     Take/one/down, pass/it/around,
     N_bottles/of/beer/on/the_wall_
   ) {}
 } catch (NoMoreBottlesLeft e) {
   writefln("Go buy more beer!") ;
 }
 

}</d>

Java

Console

<java>public class Beer{

  public static void main(String[] args){
     for(int x = 99;x>=1; --x)
        System.out.println(x+"bottles of beer on the wall\n"+x+"bottles of beer\n"+"Take one down, pass it around\n"+
                 (x-1)+"bottles of beer on the wall\n");
  }

}</java>

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