Task: Number names


C++: #include <string>
#include <iostream>
using std::string;

const char* smallNumbers[] = {
  "zero", "one", "two", "three", "four", "five",
  "six", "seven", "eight", "nine", "ten",
  "eleven", "twelve", "thirteen", "fourteen", "fifteen",
  "sixteen", "seventeen", "eighteen", "nineteen"
};
 
string spellHundreds(unsigned n) {
  string res;
  if (n > 99) {
    res = smallNumbers[n/100];
    res += " hundred";
    n %= 100;
    if (n) res += " and ";
  }
  if (n >= 20) {
    static const char* Decades[] = {
      "", "", "twenty", "thirty", "forty",
      "fifty", "sixty", "seventy", "eighty", "ninety"
    };
    res += Decades[n/10];
    n %= 10;
    if (n) res += "-";
  }
  if (n < 20 && n > 0)
    res += smallNumbers[n];
  return res;
}


const char* thousandPowers[] = {
  " billion", " million",  " thousand", "" };

typedef unsigned long Spellable;

string spell(Spellable n) {
  if (n < 20) return smallNumbers[n];
  string res;
  const char** pScaleName = thousandPowers;
  Spellable scaleFactor = 1000000000;	
  while (scaleFactor > 0) {
    if (n >= scaleFactor) {
      Spellable h = n / scaleFactor;
      res += spellHundreds(h) + *pScaleName;
      n %= scaleFactor;
      if (n) res += ", ";
    }
    scaleFactor /= 1000;
    ++pScaleName;
  }
  return res;
}

int main() {
#define SPELL_IT(x) std::cout << #x " " << spell(x) << std::endl;
  SPELL_IT(      99);
  SPELL_IT(     300);
  SPELL_IT(     310);
  SPELL_IT(    1501);
  SPELL_IT(   12609);
  SPELL_IT(  512609);
  SPELL_IT(43112609);
  SPELL_IT(1234567890);
  return 0;
}




Java: module NumberNames
    {
    void run()
        {
        @Inject Console console;

        Int[] tests = [0, 1, -1, 11, -17, 42, 99, 100, 101, -111, 1000, 1234, 10000, 100000,
                       123456789000, 0x123456789ABCDEF];
        for (Int test : tests)
            {
            console.print($"{test} = {toEnglish(test)}");
            }
        }

    static String[] digits = ["zero", "one", "two", "three", "four",
                              "five", "six", "seven", "eight", "nine"];
    static String[] teens  = ["ten", "eleven", "twelve", "thirteen", "fourteen",
                              "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
    static String[] tens   = ["zero", "ten", "twenty", "thirty", "forty",
                              "fifty", "sixty", "seventy", "eighty", "ninety"];
    static String[] ten3rd = ["?", "thousand", "million", "billion", "trillion",
                              "quadrillion", "quintillion"];

    static String toEnglish(Int n)
        {
        StringBuffer buf = new StringBuffer();
        if (n < 0)
            {
            "negative ".appendTo(buf);
            n = -n;
            }

        format3digits(n, buf);
        return buf.toString();
        }

    static void format3digits(Int n, StringBuffer buf, Int nested=0)
        {
        (Int left, Int right) = n /% 1000;
        if (left != 0)
            {
            format3digits(left, buf, nested+1);
            }

        if (right != 0 || (left == 0 && nested==0))
            {
            if (right >= 100)
                {
                (left, right) = (right /% 100);
                digits[left].appendTo(buf);
                " hundred ".appendTo(buf);
                if (right != 0)
                    {
                    format2digits(right, buf);
                    }
                }
            else
                {
                format2digits(right, buf);
                }

            if (nested > 0)
                {
                ten3rd[nested].appendTo(buf).add(' ');
                }
            }
        }

    static void format2digits(Int n, StringBuffer buf)
        {
        switch (n)
            {
            case 0..9:
                digits[n].appendTo(buf).add(' ');
                break;

            case 10..19:
                teens[n-10].appendTo(buf).add(' ');
                break;

            default:
                (Int left, Int right) = n /% 10;
                tens[left].appendTo(buf);
                if (right == 0)
                    {
                    buf.add(' ');
                    }
                else
                    {
                    buf.add('-');
                    digits[right].appendTo(buf).add(' ');
                    }
                break;
            }
        }
    }