numerical 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +0 -0
- data/README.md +0 -0
- data/lib/numerical.rb +116 -0
- data/lib/numerical/version.rb +3 -0
- data/spec/numerical_spec.rb +199 -0
- data/spec/spec_helper.rb +2 -0
- metadata +86 -0
data/LICENSE
ADDED
File without changes
|
data/README.md
ADDED
File without changes
|
data/lib/numerical.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
module Numerical
|
2
|
+
NUMBERS = {
|
3
|
+
"zero" => 0,
|
4
|
+
"one" => 1,
|
5
|
+
"two" => 2,
|
6
|
+
"three" => 3,
|
7
|
+
"four" => 4,
|
8
|
+
"five" => 5,
|
9
|
+
"six" => 6,
|
10
|
+
"seven" => 7,
|
11
|
+
"eight" => 8,
|
12
|
+
"nine" => 9,
|
13
|
+
"ten" => 10,
|
14
|
+
"eleven" => 11,
|
15
|
+
"twelve" => 12,
|
16
|
+
"thirteen" => 13,
|
17
|
+
"fourteen" => 14,
|
18
|
+
"fifteen" => 15,
|
19
|
+
"sixteen" => 16,
|
20
|
+
"seventeen" => 17,
|
21
|
+
"eighteen" => 18,
|
22
|
+
"nineteen" => 19,
|
23
|
+
"twenty" => 20,
|
24
|
+
"thirty" => 30,
|
25
|
+
"forty" => 40,
|
26
|
+
"fifty" => 50,
|
27
|
+
"sixty" => 60,
|
28
|
+
"seventy" => 70,
|
29
|
+
"eighty" => 80,
|
30
|
+
"ninety" => 90,
|
31
|
+
}
|
32
|
+
|
33
|
+
REVERSE_NUMBERS = NUMBERS.invert
|
34
|
+
|
35
|
+
SHORT_FORM = {
|
36
|
+
"thousand" => 1_000,
|
37
|
+
"million" => 1_000_000,
|
38
|
+
"billion" => 1_000_000_000,
|
39
|
+
"trillion" => 1_000_000_000_000,
|
40
|
+
"quadrillion" => 1_000_000_000_000_000,
|
41
|
+
"quintillion" => 1_000_000_000_000_000_000,
|
42
|
+
"sextillion" => 1_000_000_000_000_000_000_000,
|
43
|
+
"septillion" => 1_000_000_000_000_000_000_000_000,
|
44
|
+
"octillion" => 1_000_000_000_000_000_000_000_000_000,
|
45
|
+
"nonillion" => 1_000_000_000_000_000_000_000_000_000_000,
|
46
|
+
"decillion" => 1_000_000_000_000_000_000_000_000_000_000_000,
|
47
|
+
"undecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000,
|
48
|
+
"duodecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
49
|
+
"tredecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
50
|
+
"quattuordecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
51
|
+
"quindecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
52
|
+
"sexdecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
53
|
+
"septendecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
54
|
+
"octodecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
55
|
+
"novemdecillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
56
|
+
"vigintillion" => 1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000,
|
57
|
+
}
|
58
|
+
|
59
|
+
REVERSE_SHORT_FORM = SHORT_FORM.invert
|
60
|
+
|
61
|
+
def self.encode(number)
|
62
|
+
# TODO recursion sucks
|
63
|
+
result = ''
|
64
|
+
|
65
|
+
if number < 21
|
66
|
+
result << REVERSE_NUMBERS[number]
|
67
|
+
elsif number < 100
|
68
|
+
result << REVERSE_NUMBERS[(number / 10) * 10]
|
69
|
+
if number % 10 != 0
|
70
|
+
result << '-' + REVERSE_NUMBERS[number % 10]
|
71
|
+
end
|
72
|
+
elsif number < 1000
|
73
|
+
result << REVERSE_NUMBERS[number / 100] + ' hundred'
|
74
|
+
if number % 100 != 0
|
75
|
+
result << ' and ' + Numerical.encode(number % 100)
|
76
|
+
end
|
77
|
+
else
|
78
|
+
magnitude = 1000 ** Math.log(number, 1000).floor
|
79
|
+
|
80
|
+
result << Numerical.encode(number / magnitude) + ' ' + REVERSE_SHORT_FORM[magnitude]
|
81
|
+
|
82
|
+
if number % magnitude != 0
|
83
|
+
result << ', ' + Numerical.encode(number % magnitude)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
result
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.decode(text)
|
91
|
+
result = 0
|
92
|
+
|
93
|
+
current = 0
|
94
|
+
|
95
|
+
text.gsub! /(\d),(\d)/, "\\1\\2"
|
96
|
+
|
97
|
+
text.split(/[ \-,]+/).each do |word|
|
98
|
+
if /^\d+$/.match word
|
99
|
+
current += word.to_i
|
100
|
+
elsif NUMBERS.include? word
|
101
|
+
current += NUMBERS[word]
|
102
|
+
elsif "hundred" == word
|
103
|
+
current *= 100
|
104
|
+
elsif SHORT_FORM.include? word
|
105
|
+
result += current * SHORT_FORM[word]
|
106
|
+
current = 0
|
107
|
+
elsif "and" == word
|
108
|
+
# ignore...
|
109
|
+
else
|
110
|
+
raise ArgumentError, "Invalid text"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
result += current
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Numerical do
|
4
|
+
describe ".encode" do
|
5
|
+
it "should handle basic numbers" do
|
6
|
+
Numerical.encode(0).should == "zero"
|
7
|
+
Numerical.encode(1).should == "one"
|
8
|
+
Numerical.encode(2).should == "two"
|
9
|
+
Numerical.encode(3).should == "three"
|
10
|
+
Numerical.encode(4).should == "four"
|
11
|
+
Numerical.encode(5).should == "five"
|
12
|
+
Numerical.encode(6).should == "six"
|
13
|
+
Numerical.encode(7).should == "seven"
|
14
|
+
Numerical.encode(8).should == "eight"
|
15
|
+
Numerical.encode(9).should == "nine"
|
16
|
+
Numerical.encode(10).should == "ten"
|
17
|
+
Numerical.encode(11).should == "eleven"
|
18
|
+
Numerical.encode(12).should == "twelve"
|
19
|
+
Numerical.encode(13).should == "thirteen"
|
20
|
+
Numerical.encode(14).should == "fourteen"
|
21
|
+
Numerical.encode(15).should == "fifteen"
|
22
|
+
Numerical.encode(16).should == "sixteen"
|
23
|
+
Numerical.encode(17).should == "seventeen"
|
24
|
+
Numerical.encode(18).should == "eighteen"
|
25
|
+
Numerical.encode(19).should == "nineteen"
|
26
|
+
Numerical.encode(20).should == "twenty"
|
27
|
+
Numerical.encode(30).should == "thirty"
|
28
|
+
Numerical.encode(40).should == "forty"
|
29
|
+
Numerical.encode(50).should == "fifty"
|
30
|
+
Numerical.encode(60).should == "sixty"
|
31
|
+
Numerical.encode(70).should == "seventy"
|
32
|
+
Numerical.encode(80).should == "eighty"
|
33
|
+
Numerical.encode(90).should == "ninety"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should handle complicated numbers" do
|
37
|
+
Numerical.encode(21).should == "twenty-one"
|
38
|
+
Numerical.encode(32).should == "thirty-two"
|
39
|
+
Numerical.encode(43).should == "forty-three"
|
40
|
+
Numerical.encode(54).should == "fifty-four"
|
41
|
+
Numerical.encode(65).should == "sixty-five"
|
42
|
+
Numerical.encode(76).should == "seventy-six"
|
43
|
+
Numerical.encode(87).should == "eighty-seven"
|
44
|
+
Numerical.encode(98).should == "ninety-eight"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should handle large numbers" do
|
48
|
+
Numerical.encode(1_000).should == "one thousand"
|
49
|
+
Numerical.encode(2_000_000).should == "two million"
|
50
|
+
Numerical.encode(3_000_000_000).should == "three billion"
|
51
|
+
Numerical.encode(4_000_000_000_000).should == "four trillion"
|
52
|
+
Numerical.encode(5_000_000_000_000_000).should == "five quadrillion"
|
53
|
+
Numerical.encode(6_000_000_000_000_000_000).should == "six quintillion"
|
54
|
+
Numerical.encode(7_000_000_000_000_000_000_000).should == "seven sextillion"
|
55
|
+
Numerical.encode(8_000_000_000_000_000_000_000_000).should == "eight septillion"
|
56
|
+
Numerical.encode(9_000_000_000_000_000_000_000_000_000).should == "nine octillion"
|
57
|
+
Numerical.encode(10_000_000_000_000_000_000_000_000_000_000).should == "ten nonillion"
|
58
|
+
Numerical.encode(11_000_000_000_000_000_000_000_000_000_000_000).should == "eleven decillion"
|
59
|
+
Numerical.encode(12_000_000_000_000_000_000_000_000_000_000_000_000).should == "twelve undecillion"
|
60
|
+
Numerical.encode(13_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "thirteen duodecillion"
|
61
|
+
Numerical.encode(14_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "fourteen tredecillion"
|
62
|
+
Numerical.encode(15_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "fifteen quattuordecillion"
|
63
|
+
Numerical.encode(16_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "sixteen quindecillion"
|
64
|
+
Numerical.encode(17_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "seventeen sexdecillion"
|
65
|
+
Numerical.encode(18_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "eighteen septendecillion"
|
66
|
+
Numerical.encode(19_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "nineteen octodecillion"
|
67
|
+
Numerical.encode(20_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "twenty novemdecillion"
|
68
|
+
Numerical.encode(21_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000).should == "twenty-one vigintillion"
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should handle hundreds" do
|
72
|
+
Numerical.encode(100).should == "one hundred"
|
73
|
+
Numerical.encode(200_000).should == "two hundred thousand"
|
74
|
+
Numerical.encode(300_000_000).should == "three hundred million"
|
75
|
+
Numerical.encode(400_000_000_000).should == "four hundred billion"
|
76
|
+
Numerical.encode(500_000_000_000_000).should == "five hundred trillion"
|
77
|
+
Numerical.encode(600_000_000_000_000_000).should == "six hundred quadrillion"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should handle complicated large numbers" do
|
81
|
+
Numerical.encode(1305).should == "one thousand, three hundred and five"
|
82
|
+
Numerical.encode(32500000).should == "thirty-two million, five hundred thousand"
|
83
|
+
Numerical.encode(553_920_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_025).should == "five hundred and fifty-three vigintillion, nine hundred and twenty novemdecillion, twenty-five"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe ".decode" do
|
88
|
+
it "should handle basic numbers" do
|
89
|
+
Numerical.decode("zero").should == 0
|
90
|
+
Numerical.decode("one").should == 1
|
91
|
+
Numerical.decode("two").should == 2
|
92
|
+
Numerical.decode("three").should == 3
|
93
|
+
Numerical.decode("four").should == 4
|
94
|
+
Numerical.decode("five").should == 5
|
95
|
+
Numerical.decode("six").should == 6
|
96
|
+
Numerical.decode("seven").should == 7
|
97
|
+
Numerical.decode("eight").should == 8
|
98
|
+
Numerical.decode("nine").should == 9
|
99
|
+
Numerical.decode("ten").should == 10
|
100
|
+
Numerical.decode("eleven").should == 11
|
101
|
+
Numerical.decode("twelve").should == 12
|
102
|
+
Numerical.decode("thirteen").should == 13
|
103
|
+
Numerical.decode("fourteen").should == 14
|
104
|
+
Numerical.decode("fifteen").should == 15
|
105
|
+
Numerical.decode("sixteen").should == 16
|
106
|
+
Numerical.decode("seventeen").should == 17
|
107
|
+
Numerical.decode("eighteen").should == 18
|
108
|
+
Numerical.decode("nineteen").should == 19
|
109
|
+
Numerical.decode("twenty").should == 20
|
110
|
+
Numerical.decode("thirty").should == 30
|
111
|
+
Numerical.decode("forty").should == 40
|
112
|
+
Numerical.decode("fifty").should == 50
|
113
|
+
Numerical.decode("sixty").should == 60
|
114
|
+
Numerical.decode("seventy").should == 70
|
115
|
+
Numerical.decode("eighty").should == 80
|
116
|
+
Numerical.decode("ninety").should == 90
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should handle complicated numbers" do
|
120
|
+
Numerical.decode("twenty one").should == 21
|
121
|
+
Numerical.decode("thirty two").should == 32
|
122
|
+
Numerical.decode("forty three").should == 43
|
123
|
+
Numerical.decode("fifty four").should == 54
|
124
|
+
Numerical.decode("sixty five").should == 65
|
125
|
+
Numerical.decode("seventy six").should == 76
|
126
|
+
Numerical.decode("eighty seven").should == 87
|
127
|
+
Numerical.decode("ninety eight").should == 98
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should handle large numbers" do
|
131
|
+
Numerical.decode("one thousand").should == 1_000
|
132
|
+
Numerical.decode("two million").should == 2_000_000
|
133
|
+
Numerical.decode("three billion").should == 3_000_000_000
|
134
|
+
Numerical.decode("four trillion").should == 4_000_000_000_000
|
135
|
+
Numerical.decode("five quadrillion").should == 5_000_000_000_000_000
|
136
|
+
Numerical.decode("six quintillion").should == 6_000_000_000_000_000_000
|
137
|
+
Numerical.decode("seven sextillion").should == 7_000_000_000_000_000_000_000
|
138
|
+
Numerical.decode("eight septillion").should == 8_000_000_000_000_000_000_000_000
|
139
|
+
Numerical.decode("nine octillion").should == 9_000_000_000_000_000_000_000_000_000
|
140
|
+
Numerical.decode("ten nonillion").should == 10_000_000_000_000_000_000_000_000_000_000
|
141
|
+
Numerical.decode("eleven decillion").should == 11_000_000_000_000_000_000_000_000_000_000_000
|
142
|
+
Numerical.decode("twelve undecillion").should == 12_000_000_000_000_000_000_000_000_000_000_000_000
|
143
|
+
Numerical.decode("thirteen duodecillion").should == 13_000_000_000_000_000_000_000_000_000_000_000_000_000
|
144
|
+
Numerical.decode("fourteen tredecillion").should == 14_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
145
|
+
Numerical.decode("fifteen quattuordecillion").should == 15_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
146
|
+
Numerical.decode("sixteen quindecillion").should == 16_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
147
|
+
Numerical.decode("seventeen sexdecillion").should == 17_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
148
|
+
Numerical.decode("eighteen septendecillion").should == 18_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
149
|
+
Numerical.decode("nineteen octodecillion").should == 19_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
150
|
+
Numerical.decode("twenty novemdecillion").should == 20_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
151
|
+
Numerical.decode("twenty one vigintillion").should == 21_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should handle hundreds" do
|
155
|
+
Numerical.decode("one hundred").should == 100
|
156
|
+
Numerical.decode("two hundred thousand").should == 200_000
|
157
|
+
Numerical.decode("three hundred million").should == 300_000_000
|
158
|
+
Numerical.decode("four hundred billion").should == 400_000_000_000
|
159
|
+
Numerical.decode("five hundred trillion").should == 500_000_000_000_000
|
160
|
+
Numerical.decode("six hundred quadrillion").should == 600_000_000_000_000_000
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should handle complicated large numbers" do
|
164
|
+
Numerical.decode("one thousand three hundred five").should == 1305
|
165
|
+
Numerical.decode("thirty two million five hundred thousand").should == 32500000
|
166
|
+
Numerical.decode("five hundred fifty three vigintillion nine hundred twenty novemdecillion twenty five").should == 553_920_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000_025
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should throw an error for invalid numbers" do
|
170
|
+
lambda { Numerical.decode('one zillion') }.should raise_error
|
171
|
+
lambda { Numerical.decode('twenty gazillion three hundred thousand') }.should raise_error
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should allow some words" do
|
175
|
+
Numerical.decode("one thousand and twenty three").should == 1023
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should allow hyphens" do
|
179
|
+
Numerical.decode("twenty-one").should == 21
|
180
|
+
Numerical.decode("forty-two").should == 42
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should support numeric characters" do
|
184
|
+
Numerical.decode("23").should == 23
|
185
|
+
Numerical.decode("1 hundred").should == 100
|
186
|
+
Numerical.decode("2 hundred thousand").should == 200_000
|
187
|
+
Numerical.decode("3 hundred million").should == 300_000_000
|
188
|
+
Numerical.decode("4 hundred billion").should == 400_000_000_000
|
189
|
+
Numerical.decode("5 hundred trillion").should == 500_000_000_000_000
|
190
|
+
Numerical.decode("600 quadrillion").should == 600_000_000_000_000_000
|
191
|
+
Numerical.decode("1,000,000").should == 1_000_000
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should allow commas" do
|
195
|
+
Numerical.decode("five thousand, three hundred, twenty one").should == 5321
|
196
|
+
Numerical.decode("nine thousand, fifty three").should == 9053
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: numerical
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Daniel Knell
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Bi-Directional conversion between english language numbers (e.g. 'three
|
47
|
+
hundred') and integers
|
48
|
+
email:
|
49
|
+
- contact@danielknell.co.uk
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- lib/numerical/version.rb
|
55
|
+
- lib/numerical.rb
|
56
|
+
- LICENSE
|
57
|
+
- README.md
|
58
|
+
- spec/numerical_spec.rb
|
59
|
+
- spec/spec_helper.rb
|
60
|
+
homepage: http://github.com/artisanofcode/ruby-numerical
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.8.23
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: English language number parsing and generation for ruby
|
84
|
+
test_files:
|
85
|
+
- spec/numerical_spec.rb
|
86
|
+
- spec/spec_helper.rb
|