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









Fortran: program spell

  implicit none
  integer :: e
  integer :: i
  integer :: m
  integer :: n
  character (9), dimension (19), parameter :: small =       &
    & (/'one      ', 'two      ', 'three    ', 'four     ', &
    &   'five     ', 'six      ', 'seven    ', 'eight    ', &
    &   'nine     ', 'ten      ', 'eleven   ', 'twelve   ', &
    &   'thirteen ', 'fourteen ', 'fifteen  ', 'sixteen  ', &
    &   'seventeen', 'eighteen ', 'nineteen '/)
  character (7), dimension (2 : 9), parameter :: tens =        &
    & (/'twenty ', 'thirty ', 'forty  ', 'fifty  ', 'sixty  ', &
    &   'seventy', 'eighty ', 'ninety '/)
  character (8), dimension (3), parameter :: big = &
    & (/'thousand', 'million ', 'billion '/)
  character (256) :: r

  do
    read (*, *, iostat = i) n
    if (i /= 0) then
      exit
    end if
    if (n == 0) then
      r = 'zero'
    else
      r = ''
      m = abs (n)
      e = 0
      do
        if (m == 0) then
          exit
        end if
        if (modulo (m, 1000) > 0) then
          if (e > 0) then
            r = trim (big (e)) // ' ' // r
          end if
          if (modulo (m, 100) > 0) then
            if (modulo (m, 100) < 20) then
              r = trim (small (modulo (m, 100))) // ' ' // r
            else
              if (modulo (m, 10) > 0) then
                r = trim (small (modulo (m, 10))) // ' ' // r
                r = trim (tens (modulo (m, 100) / 10)) // '-' // r
              else
                r = trim (tens (modulo (m, 100) / 10)) // ' ' // r
              end if
            end if
          end if
          if (modulo (m, 1000) / 100 > 0) then
            r = 'hundred' // ' ' // r
            r = trim (small (modulo (m, 1000) / 100)) // ' ' // r
          end if
        end if
        m = m / 1000
        e = e + 1
      end do
      if (n < 0) then
        r = 'negative' // ' ' // r
      end if
    end if
    write (*, '(a)') trim (r)
  end do

end program spell