numerical 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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