Task

Show how to spell out a number in English.

You can use a preexisting implementation or roll your own, but you should support inputs up to at least one million (or the maximum value of your language's default bounded integer type, if that's less).

Support for inputs other than positive integers (like zero, negative integers, and floating-point numbers) is optional.



Related task

   Spelling of ordinal numbers.


SMALL = %w(zero one two three four five six seven eight nine ten
           eleven twelve thirteen fourteen fifteen sixteen seventeen
           eighteen nineteen)
 
TENS = %w(wrong wrong twenty thirty forty fifty sixty seventy
          eighty ninety)
 
BIG = [nil, "thousand"] +
      %w( m b tr quadr quint sext sept oct non dec).map{ |p| "#{p}illion" }
 
def wordify number
  case
  when number < 0
    "negative #{wordify -number}"
 
  when number < 20
    SMALL[number]
 
  when number < 100
    div, mod = number.divmod(10)
    TENS[div] + (mod==0 ? "" : "-#{wordify mod}")
 
  when number < 1000
    div, mod = number.divmod(100)
    "#{SMALL[div]} hundred" + (mod==0 ? "" : " and #{wordify mod}")
 
  else
    # separate into 3-digit chunks
    chunks = []
    div = number
    while div != 0
      div, mod = div.divmod(1000)
      chunks << mod                 # will store smallest to largest
    end
 
    raise ArgumentError, "Integer value too large." if chunks.size > BIG.size
 
    chunks.map{ |c| wordify c }.
           zip(BIG).    # zip pairs up corresponding elements from the two arrays
           find_all { |c| c[0] != 'zero' }.
           map{ |c| c.join ' '}.    # join ["forty", "thousand"]
           reverse.
           join(', ').              # join chunks
           strip
  end
end
 
data = [-1123, 0, 1, 20, 123, 200, 220, 1245, 2000, 2200, 2220, 467889,
        23_000_467, 23_234_467, 2_235_654_234, 12_123_234_543_543_456,
        987_654_321_098_765_432_109_876_543_210_987_654,
        123890812938219038290489327894327894723897432]
 
data.each do |n|
  print "#{n}: "
  begin
    puts "'#{wordify n}'"
  rescue => e
    puts "Error: #{e}"
  end
end