Voting

Category

real language

Bookmarking

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

Support Us

Language Javascript

(With english numbers, DOM, and callbacks)

Date:01/18/08
Author:Joseph Taylor
URL:http://www.textninja.net
Comments:0
Info:http://developer.mozilla.org/en/docs/About_JavaScript
Score: (2.60 in 5 votes)
var secondsPerVerse = 0.001;

function bottles(n, capitalize) {
  return (capitalize ? english(n).capitalize() : english(n)) + " " + maybeAddAnS("bottle", n) + "
of beer";
}

function drinkAlotOfBeer(numberOfBottles, actionToPerformOnVerse, depth) {

  var stillDrinkingBeer = true;
  var justReplenishedSupply = false;
  if (!depth) depth = 0;
  depth++;

  var takeOneDownAndPassItAround = function() {
    numberOfBottles--;
  }

  var thereIsNoMoreBeer = function() {
    return !(numberOfBottles > 0);
  }

  var replenishBeerSupply = function() {
    numberOfBottles = depth - 1;
    justReplenishedSupply = true;
  }

  var stopDrinkingBeer = function() {
    stillDrinkingBeer = false;
  }

  var verse = bottles(numberOfBottles, true) + " on the wall,\n" + 
              bottles(numberOfBottles) + "!\n";
          
  if (thereIsNoMoreBeer()) {
    verse += "Go to the store, buy some more,\n";
    replenishBeerSupply();
    stopDrinkingBeer();
  } else {
    verse += "Take " + (numberOfBottles == 1 ? "it" : "one") + " down, pass it around,\n";
    takeOneDownAndPassItAround();
  }

  verse += bottles(numberOfBottles) + " on the wall" + (justReplenishedSupply ? "!" : ".");

  if (stillDrinkingBeer) {
    return actionToPerformOnVerse(verse, [drinkAlotOfBeer, numberOfBottles, actionToPerformOnVerse,
depth]);
  } else {
    return actionToPerformOnVerse(verse);
  }
}

var beerSongViewer = document.body.appendChild(document.createElement("pre"));
function displayVerseFancily(verseText, continueAt) {
  beerSongViewer.innerHTML = verseText;
  if (continueAt) {
    setTimeout(function() { continueAt[0](continueAt[1], continueAt[2], continueAt[3]) },
Math.floor(secondsPerVerse * 1000));
  }
}

function maybeAddAnS(word, n) {
  if (n == 1) {
    return word;
  } else {
    return word + "s";
  }
}

function english(n, args) {
  if (!args) args = {};
  var smallNumbers = ["no more", "one", "two", "three", "four",
                      "five", "six", "seven", "eight", "nine", "ten",
                      "eleven", "twelve", "thirteen", "fourteen",
                      "fifteen", "sixteen", "seventeen", "eighteen",
                      "nineteen"];
  var multiplesOfTen = ["", "", "twenty", "thirty", "fourty", "fifty",
                        "sixty", "seventy", "eighty", "ninety"];
  var reallyBigNumbers = {
    "hundred" : 100,
    "thousand" : 1000,
    "million" : 1000000,
    "billion" : 1000000000,
    "trillion" : 1000000000000
  };
  if (n < smallNumbers.length) {
    if (n == 0 && args.recursing) {
      return null;
    } else {
      return smallNumbers[n];
    }
  } else if (n < 100) {
    args.recursing = true;
    var remainder = n % 10;
    var quotient = Math.floor(n / 10);
    var startOfNumber = multiplesOfTen[quotient];
    var endOfNumber = english(remainder, args);

    if (!endOfNumber) {
      return startOfNumber;
    } else {
      return [startOfNumber, endOfNumber].join("-");
    }
  } else {
    args.recursing = true;
    var biggestNumberThatFits = 0;
    var nameForBiggestNumberThatFits = "zero";
    for (var i in reallyBigNumbers) {
      if (reallyBigNumbers[i] <= n) {
        if (reallyBigNumbers[i] > biggestNumberThatFits) {
          biggestNumberThatFits = reallyBigNumbers[i];
          nameForBiggestNumberThatFits = i;
        }
      }
    }

    var remainder = n % biggestNumberThatFits;
    var quotient = Math.floor(n / biggestNumberThatFits);

    var startOfNumber = "";
    startOfNumber = english(quotient, args);

    var middleOfNumber = nameForBiggestNumberThatFits;
    var endOfNumber = english(remainder, args);

    var number = [startOfNumber, middleOfNumber, endOfNumber];
    if (!startOfNumber) number.shift();
    if (!endOfNumber) number.pop();

    return number.join(" ");
  }
}

String.prototype.capitalize = function() {
  return this.charAt(0).toUpperCase() + this.substring(1);
}

drinkAlotOfBeer(1000, displayVerseFancily);

Download Source | Write Comment

Alternative Versions

VersionAuthorDateCommentsRate
Eponymous obfuscated versionJavaScribe01/09/094
using DOM and a closureChristof Donat03/07/060
Fully commented, OOP approach.Ariel Flesler03/28/080
4Brian Patrick Lee04/20/053

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: