numerical 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,3 @@
1
+ module Numerical
2
+ VERSION = '0.0.1'
3
+ 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
@@ -0,0 +1,2 @@
1
+ require 'rspec'
2
+ require 'numerical'
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