Task: Number names





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;
            }
        }
    }


PHP: $orderOfMag = array('Hundred', 'Thousand,', 'Million,', 'Billion,', 'Trillion,');
$smallNumbers = array('Zero', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine',
'Ten', 'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen');
$decades = array('', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety');

function NumberToEnglish($num, $count = 0){
   global $orderOfMag, $smallNumbers, $decades;
   $isLast = true;
   $str = '';

   if ($num < 0){
      $str = 'Negative ';
      $num = abs($num);
   }

   (int) $thisPart = substr((string) $num, -3);

   if (strlen((string) $num) > 3){

      $str .= NumberToEnglish((int) substr((string) $num, 0, strlen((string) $num) - 3), $count + 1);
      $isLast = false;
   }

   if (($count == 0 || $isLast) && ($str == '' || $str == 'Negative '))

      $and = '';
   else
      $and = ' and ';

   if ($thisPart > 99){

      $str .= ($isLast ? '' : ' ') . "{$smallNumbers[$thisPart/100]} {$orderOfMag[0]}";

      if(($thisPart %= 100) == 0){

         $str .= " {$orderOfMag[$count]}";
         return $str;
      }
      $and = ' and ';  // Set up our and string to the word "and" since there is something in the hundreds place of this chunk
   }

   if ($thisPart >= 20){

      $str .= "{$and}{$decades[$thisPart /10]}";
      $and = ' '; // Make sure we don't have any extranious "and"s
      if(($thisPart %= 10) == 0)
         return $str . ($count != 0 ? " {$orderOfMag[$count]}" : '');
   }

   if ($thisPart < 20 && $thisPart > 0)

      return $str . "{$and}{$smallNumbers[(int) $thisPart]} " . ($count != 0 ? $orderOfMag[$count] : '');
   elseif ($thisPart == 0 && strlen($thisPart) == 1)

      return $str . "{$smallNumbers[(int)$thisPart]}";
}