Browse | Submit A New Snippet | Create A Package

## EnglishNumerals

Type:
Class
Category:
Math Functions
Language:
Ruby

Description:
=begin
While we normally write numbers using Arabic (or since Quiz #22,
Roman) numerals, numbers can also be written out as English phrases.

For example:

7 == seven (the hard way)
42 == forty-two (a very important number)
2001 == two thousand and one (a space odyssey)
1999 == (party like it's) nineteen hundred and ninety-nine

So the quiz is a problem from a Pi Mu Epsilon (US national math club)

"When the integers 1 to 10_000_000_000 are written in the English
language, then sorted as strings, which odd number appears first in
the list?"

- Create Ruby code to translate a number to it's English language form.

- Determine programatically which odd number in 1..10_000_000_000
would sort first if written in English. (Brute force is the obvious
solution, but the computer may have to think about it...)

- Would the answer change for a larger range of values, say 10**30?

- Do French and German Rubyists get a different answer than the
Americans?

=end

### Versions Of This Snippet::

zhang bee
 Snippet ID Download Version Date Posted Author Delete 439 0.1 2009-02-09 06:40 zhang bee

## Latest Snippet Version: :0.1

```module EnglishNumerals

Numbers = {
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
10 => 'ten',
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
20 => 'twenty',
30 => 'thirty',
40 => 'forty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety'
}

AmExponents = {
3 => 'thousand',
6 => 'million',
9 => 'billion',
12 => 'trillion',
18 => 'quintillion',
21 => 'sexillion',
24 => 'septillion',
27 => 'octillion',
30 => 'nonillion',
33 => 'decillion',
36 => 'undecillion',
39 => 'duodecillion',
42 => 'tredecillion',
45 => 'quattuordecillion',
48 => 'quindecillion',
51 => 'sexdecillion',
54 => 'septendecillion',
57 => 'octodecillion',
60 => 'novemdecillion',
63 => 'vigintillion',
66 => 'unvigintillion',
69 => 'duovigintillion'
}
Digits = [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69]
EurExponents = {
3 => 'thousand',
6 => 'million',
9 => 'milliard',
12 => 'billion',
15 => 'billiard',
18 => 'trillion',
21 => 'trilliard',
30 => 'quintillion',
33 => 'quintilliard',
36 => 'sextillion',
39 => 'sextilliard',
42 => 'septillion',
45 => 'septilliard',
48 => 'octillion',
51 => 'octilliard',
54 => 'noventillion',
57 => 'noventilliard',
60 => 'decillion',
63 => 'decilliard',
66 => 'undecillion',
69 => 'undecilliard'
}

Max_exponent = 69

def self.to_English(val, eu_names = true, include_and = true)

val = val.to_i.abs
return "zero" if val == 0

include_and = false if val <= 100

exp_hash = eu_names ? EurExponents : AmExponents

vals = []
while val > 0
vals << val % 1000
val = val / 1000
end
s_num = ""
vals.each_index do |i|
if i == 0
s_num = self.h_Small(vals[i],include_and)
else
s_num = self.h_Small(vals[i],include_and) + " " + exp_hash[Digits[i-1]] + " " + s_num if vals[i] != 0
end
end
s_num
end
def self.to_American(val, include_and = true)
self.to_English(val, false, include_and)
end
def self.h_Small(h,include_and = false)
return "" if h <= 0
num1 = h % 100
h_num = ""
if num1 != 0
if num1 <= 20
h_num = Numbers[num1]
else
h_num << Numbers[(num1/10)*10]
h_num << "-" << Numbers[num1%10] if num1%10 != 0
end
end
h_num2 = ""
if h >= 100
h_num2 = Numbers[h / 100]
if include_and
h_num2 += " hundred "
h_num2 += ("and " + h_num) if h_num != ""
else
h_num2 += " hundred "
h_num2 += h_num if h_num != ""
end
h_num2
else
h_num
end
end
end

# If no argument, then work in interactive mode
#
if !ARGV[0] || ARGV[0].to_i == 0 then

\$<.each_line { |line|
puts EnglishNumerals.to_English(line.chomp)
puts EnglishNumerals.to_American(line.chomp)
}
end

```

### Submit a new version

You can submit a new version of this snippet if you have modified it and you feel it is appropriate to share with others..