Voting

Category

real language

Bookmarking

Del.icio.us Digg Diigo DZone Earthlink Google Kick.ie
Windows Live LookLater Ma.gnolia Reddit Rojo StumbleUpon Technorati

Language D

(Div Operator Edition)

Date:02/29/08
Author:badmadevil
URL:n/a
Comments:0
Info:http://www.digitalmars.com/d/
Score: (2.50 in 6 votes)
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!") ;
  }
 
}
// first post at

Download Source | Write Comment

Alternative Versions

VersionAuthorDateCommentsRate
1Stewart Gordon05/31/054
Template metaprogrammingDon Clugston07/11/061
D feuture's galoreFredrik Olsson10/09/052
Fiber "Ring"Bryan Knowles11/17/100
5Philipp Winterberg04/20/057

Comments

Download Source | Write Comment

Add Comment

Please provide a value for the fields Name, Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.

Please don't post large portions of code here! Use the form to submit new examples or updates instead!

Name:

eMail:

URL:

Security Code:
  
Comment: