numerical 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +8 -0
- data/README.md +40 -0
- data/bin/numerical +17 -0
- data/lib/numerical.rb +8 -111
- data/lib/numerical/constants.rb +58 -0
- data/lib/numerical/decoder.rb +32 -0
- data/lib/numerical/encoder.rb +26 -0
- data/lib/numerical/version.rb +1 -1
- data/spec/numerical/decoder_spec.rb +121 -0
- data/spec/numerical/encoder_spec.rb +90 -0
- data/spec/numerical_spec.rb +30 -174
- metadata +12 -3
data/LICENSE
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
Copyright © 2012 Daniel Knell, http://danielknell.co.uk
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
5
|
+
|
6
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
7
|
+
|
8
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
data/README.md
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Artisan Numerical
|
2
|
+
|
3
|
+
Bi-Directional conversion between english language numbers (e.g. 'three hundred') and integers
|
4
|
+
|
5
|
+
## Install
|
6
|
+
|
7
|
+
To install Artisan Numerical via gem:
|
8
|
+
|
9
|
+
gem install numerical
|
10
|
+
|
11
|
+
## Source
|
12
|
+
|
13
|
+
To install from source:
|
14
|
+
|
15
|
+
hg clone https://bitbucket.org/artisanofcode/ruby-numerical
|
16
|
+
|
17
|
+
or
|
18
|
+
|
19
|
+
git clone git://github.com/artisanofcode/ruby-numerical.git
|
20
|
+
|
21
|
+
## History
|
22
|
+
|
23
|
+
### 0.0.2
|
24
|
+
|
25
|
+
Decomposing into encoder and decoder classes
|
26
|
+
|
27
|
+
### 0.0.1
|
28
|
+
|
29
|
+
Initial Release
|
30
|
+
|
31
|
+
## Licence
|
32
|
+
|
33
|
+
This project is licensed under the [MIT licence][licence].
|
34
|
+
|
35
|
+
## Meta
|
36
|
+
|
37
|
+
This project uses [Semantic Versioning][semver].
|
38
|
+
|
39
|
+
[semver]: http://semver.org/ "Semantic Versioning"
|
40
|
+
[licence]: http://dan.mit-license.org/ "MIT licence"
|
data/bin/numerical
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "numerical"
|
3
|
+
|
4
|
+
if ARGV.count < 2 or not [ '-e', '-d' ].include? ARGV[0]
|
5
|
+
puts "usage: numerical [ -e | -d ] value"
|
6
|
+
puts ""
|
7
|
+
puts "options:"
|
8
|
+
puts " -e encode a numeric value into words"
|
9
|
+
puts " -d decode a numeric value from words"
|
10
|
+
exit(1)
|
11
|
+
end
|
12
|
+
|
13
|
+
if ARGV.shift == '-e'
|
14
|
+
puts Numerical.encode(ARGV.shift.to_i)
|
15
|
+
else
|
16
|
+
puts Numerical.decode(ARGV.join(' '))
|
17
|
+
end
|
data/lib/numerical.rb
CHANGED
@@ -1,116 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
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]
|
1
|
+
require "numerical/constants"
|
2
|
+
require "numerical/decoder"
|
3
|
+
require "numerical/encoder"
|
81
4
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
result
|
5
|
+
module Numerical
|
6
|
+
def self.encode(value)
|
7
|
+
Numerical::Encoder.new.encode(value)
|
88
8
|
end
|
89
9
|
|
90
|
-
def self.decode(
|
91
|
-
|
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
|
10
|
+
def self.decode(value)
|
11
|
+
Numerical::Decoder.new.decode(value)
|
115
12
|
end
|
116
13
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Numerical
|
2
|
+
class Constants
|
3
|
+
NUMBERS = {
|
4
|
+
"zero" => 0,
|
5
|
+
"one" => 1,
|
6
|
+
"two" => 2,
|
7
|
+
"three" => 3,
|
8
|
+
"four" => 4,
|
9
|
+
"five" => 5,
|
10
|
+
"six" => 6,
|
11
|
+
"seven" => 7,
|
12
|
+
"eight" => 8,
|
13
|
+
"nine" => 9,
|
14
|
+
"ten" => 10,
|
15
|
+
"eleven" => 11,
|
16
|
+
"twelve" => 12,
|
17
|
+
"thirteen" => 13,
|
18
|
+
"fourteen" => 14,
|
19
|
+
"fifteen" => 15,
|
20
|
+
"sixteen" => 16,
|
21
|
+
"seventeen" => 17,
|
22
|
+
"eighteen" => 18,
|
23
|
+
"nineteen" => 19,
|
24
|
+
"twenty" => 20,
|
25
|
+
"thirty" => 30,
|
26
|
+
"forty" => 40,
|
27
|
+
"fifty" => 50,
|
28
|
+
"sixty" => 60,
|
29
|
+
"seventy" => 70,
|
30
|
+
"eighty" => 80,
|
31
|
+
"ninety" => 90,
|
32
|
+
}.freeze
|
33
|
+
|
34
|
+
SHORT_FORM = {
|
35
|
+
"thousand" => 1000 ** 1,
|
36
|
+
"million" => 1000 ** 2,
|
37
|
+
"billion" => 1000 ** 3,
|
38
|
+
"trillion" => 1000 ** 4,
|
39
|
+
"quadrillion" => 1000 ** 5,
|
40
|
+
"quintillion" => 1000 ** 6,
|
41
|
+
"sextillion" => 1000 ** 7,
|
42
|
+
"septillion" => 1000 ** 8,
|
43
|
+
"octillion" => 1000 ** 9,
|
44
|
+
"nonillion" => 1000 ** 10,
|
45
|
+
"decillion" => 1000 ** 11,
|
46
|
+
"undecillion" => 1000 ** 12,
|
47
|
+
"duodecillion" => 1000 ** 13,
|
48
|
+
"tredecillion" => 1000 ** 14,
|
49
|
+
"quattuordecillion" => 1000 ** 15,
|
50
|
+
"quindecillion" => 1000 ** 16,
|
51
|
+
"sexdecillion" => 1000 ** 17,
|
52
|
+
"septendecillion" => 1000 ** 18,
|
53
|
+
"octodecillion" => 1000 ** 19,
|
54
|
+
"novemdecillion" => 1000 ** 20,
|
55
|
+
"vigintillion" => 1000 ** 21,
|
56
|
+
}.freeze
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Numerical
|
2
|
+
class Decoder
|
3
|
+
NUMBERS = Numerical::Constants::NUMBERS
|
4
|
+
|
5
|
+
SHORT_FORM = Numerical::Constants::SHORT_FORM
|
6
|
+
|
7
|
+
def decode(value)
|
8
|
+
result = 0
|
9
|
+
|
10
|
+
current = 0
|
11
|
+
|
12
|
+
value.gsub(/(\d),(\d)/, "\\1\\2").split(/[ \-,]+/).each do |word|
|
13
|
+
if /^\d+$/.match word
|
14
|
+
current += word.to_i
|
15
|
+
elsif NUMBERS.include? word
|
16
|
+
current += NUMBERS[word]
|
17
|
+
elsif "hundred" == word
|
18
|
+
current *= 100
|
19
|
+
elsif SHORT_FORM.include? word
|
20
|
+
result += current * SHORT_FORM[word]
|
21
|
+
current = 0
|
22
|
+
elsif "and" == word
|
23
|
+
# ...
|
24
|
+
else
|
25
|
+
return nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
result += current
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Numerical
|
2
|
+
class Encoder
|
3
|
+
NUMBERS = Numerical::Constants::NUMBERS.invert.freeze
|
4
|
+
|
5
|
+
SHORT_FORM = Numerical::Constants::SHORT_FORM.invert.freeze
|
6
|
+
|
7
|
+
def encode(value)
|
8
|
+
case value
|
9
|
+
when 0 .. 20
|
10
|
+
result = NUMBERS[value]
|
11
|
+
when 21 .. 99
|
12
|
+
result = NUMBERS[(value / 10) * 10]
|
13
|
+
result += '-' + NUMBERS[value % 10] if value % 10 != 0
|
14
|
+
when 100 .. 999
|
15
|
+
result = NUMBERS[value / 100] + ' hundred'
|
16
|
+
result += ' and ' + encode(value % 100) if value % 100 != 0
|
17
|
+
else
|
18
|
+
magnitude = 1000 ** Math.log(value, 1000).floor
|
19
|
+
result = encode(value / magnitude) + ' ' + SHORT_FORM[magnitude]
|
20
|
+
result += ', ' + encode(value % magnitude) if value % magnitude != 0
|
21
|
+
end
|
22
|
+
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/numerical/version.rb
CHANGED
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Numerical::Decoder do
|
4
|
+
before do
|
5
|
+
@decoder = Numerical::Decoder.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".decode" do
|
9
|
+
it "should handle basic numbers" do
|
10
|
+
@decoder.decode("zero").should == 0
|
11
|
+
@decoder.decode("one").should == 1
|
12
|
+
@decoder.decode("two").should == 2
|
13
|
+
@decoder.decode("three").should == 3
|
14
|
+
@decoder.decode("four").should == 4
|
15
|
+
@decoder.decode("five").should == 5
|
16
|
+
@decoder.decode("six").should == 6
|
17
|
+
@decoder.decode("seven").should == 7
|
18
|
+
@decoder.decode("eight").should == 8
|
19
|
+
@decoder.decode("nine").should == 9
|
20
|
+
@decoder.decode("ten").should == 10
|
21
|
+
@decoder.decode("eleven").should == 11
|
22
|
+
@decoder.decode("twelve").should == 12
|
23
|
+
@decoder.decode("thirteen").should == 13
|
24
|
+
@decoder.decode("fourteen").should == 14
|
25
|
+
@decoder.decode("fifteen").should == 15
|
26
|
+
@decoder.decode("sixteen").should == 16
|
27
|
+
@decoder.decode("seventeen").should == 17
|
28
|
+
@decoder.decode("eighteen").should == 18
|
29
|
+
@decoder.decode("nineteen").should == 19
|
30
|
+
@decoder.decode("twenty").should == 20
|
31
|
+
@decoder.decode("thirty").should == 30
|
32
|
+
@decoder.decode("forty").should == 40
|
33
|
+
@decoder.decode("fifty").should == 50
|
34
|
+
@decoder.decode("sixty").should == 60
|
35
|
+
@decoder.decode("seventy").should == 70
|
36
|
+
@decoder.decode("eighty").should == 80
|
37
|
+
@decoder.decode("ninety").should == 90
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should handle complicated numbers" do
|
41
|
+
@decoder.decode("twenty one").should == 21
|
42
|
+
@decoder.decode("thirty two").should == 32
|
43
|
+
@decoder.decode("forty three").should == 43
|
44
|
+
@decoder.decode("fifty four").should == 54
|
45
|
+
@decoder.decode("sixty five").should == 65
|
46
|
+
@decoder.decode("seventy six").should == 76
|
47
|
+
@decoder.decode("eighty seven").should == 87
|
48
|
+
@decoder.decode("ninety eight").should == 98
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should handle large numbers" do
|
52
|
+
@decoder.decode("one thousand").should == 1 * 1000 ** 1
|
53
|
+
@decoder.decode("two million").should == 2 * 1000 ** 2
|
54
|
+
@decoder.decode("three billion").should == 3 * 1000 ** 3
|
55
|
+
@decoder.decode("four trillion").should == 4 * 1000 ** 4
|
56
|
+
@decoder.decode("five quadrillion").should == 5 * 1000 ** 5
|
57
|
+
@decoder.decode("six quintillion").should == 6 * 1000 ** 6
|
58
|
+
@decoder.decode("seven sextillion").should == 7 * 1000 ** 7
|
59
|
+
@decoder.decode("eight septillion").should == 8 * 1000 ** 8
|
60
|
+
@decoder.decode("nine octillion").should == 9 * 1000 ** 9
|
61
|
+
@decoder.decode("ten nonillion").should == 10 * 1000 ** 10
|
62
|
+
@decoder.decode("eleven decillion").should == 11 * 1000 ** 11
|
63
|
+
@decoder.decode("twelve undecillion").should == 12 * 1000 ** 12
|
64
|
+
@decoder.decode("thirteen duodecillion").should == 13 * 1000 ** 13
|
65
|
+
@decoder.decode("fourteen tredecillion").should == 14 * 1000 ** 14
|
66
|
+
@decoder.decode("fifteen quattuordecillion").should == 15 * 1000 ** 15
|
67
|
+
@decoder.decode("sixteen quindecillion").should == 16 * 1000 ** 16
|
68
|
+
@decoder.decode("seventeen sexdecillion").should == 17 * 1000 ** 17
|
69
|
+
@decoder.decode("eighteen septendecillion").should == 18 * 1000 ** 18
|
70
|
+
@decoder.decode("nineteen octodecillion").should == 19 * 1000 ** 19
|
71
|
+
@decoder.decode("twenty novemdecillion").should == 20 * 1000 ** 20
|
72
|
+
@decoder.decode("twenty one vigintillion").should == 21 * 1000 ** 21
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should handle hundreds" do
|
76
|
+
@decoder.decode("one hundred").should == 100
|
77
|
+
@decoder.decode("two hundred thousand").should == 200_000
|
78
|
+
@decoder.decode("three hundred million").should == 300_000_000
|
79
|
+
@decoder.decode("four hundred billion").should == 400_000_000_000
|
80
|
+
@decoder.decode("five hundred trillion").should == 500_000_000_000_000
|
81
|
+
@decoder.decode("six hundred quadrillion").should == 600_000_000_000_000_000
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should handle complicated large numbers" do
|
85
|
+
@decoder.decode("one thousand three hundred five").should == 1305
|
86
|
+
@decoder.decode("thirty two million five hundred thousand").should == 32500000
|
87
|
+
@decoder.decode("five hundred fifty three vigintillion nine hundred twenty novemdecillion twenty five").should == 553920 * 1000 ** 20 + 25
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should return nil for invalid numbers" do
|
91
|
+
@decoder.decode('one zillion').should == nil
|
92
|
+
@decoder.decode('twenty gazillion three hundred thousand').should == nil
|
93
|
+
@decoder.decode('foobar').should == nil
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should allow some words" do
|
97
|
+
@decoder.decode("one thousand and twenty three").should == 1023
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should allow hyphens" do
|
101
|
+
@decoder.decode("twenty-one").should == 21
|
102
|
+
@decoder.decode("forty-two").should == 42
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should support numeric characters" do
|
106
|
+
@decoder.decode("23").should == 23
|
107
|
+
@decoder.decode("1 hundred").should == 100
|
108
|
+
@decoder.decode("2 hundred thousand").should == 200_000
|
109
|
+
@decoder.decode("3 hundred million").should == 300_000_000
|
110
|
+
@decoder.decode("4 hundred billion").should == 400_000_000_000
|
111
|
+
@decoder.decode("5 hundred trillion").should == 500_000_000_000_000
|
112
|
+
@decoder.decode("600 quadrillion").should == 600_000_000_000_000_000
|
113
|
+
@decoder.decode("1,000,000").should == 1_000_000
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should allow commas" do
|
117
|
+
@decoder.decode("five thousand, three hundred, twenty one").should == 5321
|
118
|
+
@decoder.decode("nine thousand, fifty three").should == 9053
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Numerical::Encoder do
|
4
|
+
before do
|
5
|
+
@encoder = Numerical::Encoder.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".encode" do
|
9
|
+
it "should handle basic numbers" do
|
10
|
+
@encoder.encode(0).should == "zero"
|
11
|
+
@encoder.encode(1).should == "one"
|
12
|
+
@encoder.encode(2).should == "two"
|
13
|
+
@encoder.encode(3).should == "three"
|
14
|
+
@encoder.encode(4).should == "four"
|
15
|
+
@encoder.encode(5).should == "five"
|
16
|
+
@encoder.encode(6).should == "six"
|
17
|
+
@encoder.encode(7).should == "seven"
|
18
|
+
@encoder.encode(8).should == "eight"
|
19
|
+
@encoder.encode(9).should == "nine"
|
20
|
+
@encoder.encode(10).should == "ten"
|
21
|
+
@encoder.encode(11).should == "eleven"
|
22
|
+
@encoder.encode(12).should == "twelve"
|
23
|
+
@encoder.encode(13).should == "thirteen"
|
24
|
+
@encoder.encode(14).should == "fourteen"
|
25
|
+
@encoder.encode(15).should == "fifteen"
|
26
|
+
@encoder.encode(16).should == "sixteen"
|
27
|
+
@encoder.encode(17).should == "seventeen"
|
28
|
+
@encoder.encode(18).should == "eighteen"
|
29
|
+
@encoder.encode(19).should == "nineteen"
|
30
|
+
@encoder.encode(20).should == "twenty"
|
31
|
+
@encoder.encode(30).should == "thirty"
|
32
|
+
@encoder.encode(40).should == "forty"
|
33
|
+
@encoder.encode(50).should == "fifty"
|
34
|
+
@encoder.encode(60).should == "sixty"
|
35
|
+
@encoder.encode(70).should == "seventy"
|
36
|
+
@encoder.encode(80).should == "eighty"
|
37
|
+
@encoder.encode(90).should == "ninety"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should handle complicated numbers" do
|
41
|
+
@encoder.encode(21).should == "twenty-one"
|
42
|
+
@encoder.encode(32).should == "thirty-two"
|
43
|
+
@encoder.encode(43).should == "forty-three"
|
44
|
+
@encoder.encode(54).should == "fifty-four"
|
45
|
+
@encoder.encode(65).should == "sixty-five"
|
46
|
+
@encoder.encode(76).should == "seventy-six"
|
47
|
+
@encoder.encode(87).should == "eighty-seven"
|
48
|
+
@encoder.encode(98).should == "ninety-eight"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should handle large numbers" do
|
52
|
+
@encoder.encode(1 * 1000 ** 1).should == "one thousand"
|
53
|
+
@encoder.encode(2 * 1000 ** 2).should == "two million"
|
54
|
+
@encoder.encode(3 * 1000 ** 3).should == "three billion"
|
55
|
+
@encoder.encode(4 * 1000 ** 4).should == "four trillion"
|
56
|
+
@encoder.encode(5 * 1000 ** 5).should == "five quadrillion"
|
57
|
+
@encoder.encode(6 * 1000 ** 6).should == "six quintillion"
|
58
|
+
@encoder.encode(7 * 1000 ** 7).should == "seven sextillion"
|
59
|
+
@encoder.encode(8 * 1000 ** 8).should == "eight septillion"
|
60
|
+
@encoder.encode(9 * 1000 ** 9).should == "nine octillion"
|
61
|
+
@encoder.encode(10 * 1000 ** 10).should == "ten nonillion"
|
62
|
+
@encoder.encode(11 * 1000 ** 11).should == "eleven decillion"
|
63
|
+
@encoder.encode(12 * 1000 ** 12).should == "twelve undecillion"
|
64
|
+
@encoder.encode(13 * 1000 ** 13).should == "thirteen duodecillion"
|
65
|
+
@encoder.encode(14 * 1000 ** 14).should == "fourteen tredecillion"
|
66
|
+
@encoder.encode(15 * 1000 ** 15).should == "fifteen quattuordecillion"
|
67
|
+
@encoder.encode(16 * 1000 ** 16).should == "sixteen quindecillion"
|
68
|
+
@encoder.encode(17 * 1000 ** 17).should == "seventeen sexdecillion"
|
69
|
+
@encoder.encode(18 * 1000 ** 18).should == "eighteen septendecillion"
|
70
|
+
@encoder.encode(19 * 1000 ** 19).should == "nineteen octodecillion"
|
71
|
+
@encoder.encode(20 * 1000 ** 20).should == "twenty novemdecillion"
|
72
|
+
@encoder.encode(21 * 1000 ** 21).should == "twenty-one vigintillion"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should handle hundreds" do
|
76
|
+
@encoder.encode(100).should == "one hundred"
|
77
|
+
@encoder.encode(200_000).should == "two hundred thousand"
|
78
|
+
@encoder.encode(300_000_000).should == "three hundred million"
|
79
|
+
@encoder.encode(400_000_000_000).should == "four hundred billion"
|
80
|
+
@encoder.encode(500_000_000_000_000).should == "five hundred trillion"
|
81
|
+
@encoder.encode(600_000_000_000_000_000).should == "six hundred quadrillion"
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should handle complicated large numbers" do
|
85
|
+
@encoder.encode(1305).should == "one thousand, three hundred and five"
|
86
|
+
@encoder.encode(32500000).should == "thirty-two million, five hundred thousand"
|
87
|
+
@encoder.encode(553920 * 1000 ** 20 + 25).should == "five hundred and fifty-three vigintillion, nine hundred and twenty novemdecillion, twenty-five"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/numerical_spec.rb
CHANGED
@@ -2,198 +2,54 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Numerical do
|
4
4
|
describe ".encode" do
|
5
|
-
it "should
|
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"
|
5
|
+
it "should encode numbers" do
|
11
6
|
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
7
|
Numerical.encode(98).should == "ninety-eight"
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
8
|
+
Numerical.encode(1 * 1000 ** 1).should == "one thousand"
|
9
|
+
Numerical.encode(21 * 1000 ** 21).should == "twenty-one vigintillion"
|
10
|
+
Numerical.encode(600 * 1000 ** 5).should == "six hundred quadrillion"
|
81
11
|
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
12
|
end
|
85
13
|
end
|
86
14
|
|
87
15
|
describe ".decode" do
|
88
|
-
it "should
|
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
|
16
|
+
it "should decode numbers" do
|
94
17
|
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
18
|
Numerical.decode("ninety eight").should == 98
|
128
|
-
|
129
|
-
|
130
|
-
|
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
|
19
|
+
Numerical.decode("one thousand").should == 1 * 1000 ** 1
|
20
|
+
Numerical.decode("twenty one vigintillion").should == 21 * 1000 ** 21
|
21
|
+
Numerical.decode("six hundred quadrillion").should == 600 * 1000 ** 5
|
164
22
|
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
23
|
end
|
24
|
+
end
|
173
25
|
|
174
|
-
|
175
|
-
|
26
|
+
it "should be able to decode encoded numbers" do
|
27
|
+
# check powers of two
|
28
|
+
i = 0
|
29
|
+
while 2 ** i < 1000 ** 22
|
30
|
+
Numerical.decode(Numerical.encode(2 ** i)).should == 2 ** i
|
31
|
+
i += 1
|
176
32
|
end
|
177
33
|
|
178
|
-
|
179
|
-
|
180
|
-
|
34
|
+
# check powers of three
|
35
|
+
i = 0
|
36
|
+
while 3 ** i < 1000 ** 22
|
37
|
+
Numerical.decode(Numerical.encode(3 ** i)).should == 3 ** i
|
38
|
+
i += 1
|
181
39
|
end
|
182
40
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
Numerical.decode(
|
187
|
-
|
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
|
41
|
+
# check powers of five
|
42
|
+
i = 0
|
43
|
+
while 5 ** i < 1000 ** 22
|
44
|
+
Numerical.decode(Numerical.encode(5 ** i)).should == 5 ** i
|
45
|
+
i += 1
|
192
46
|
end
|
193
47
|
|
194
|
-
|
195
|
-
|
196
|
-
|
48
|
+
# check powers of seven
|
49
|
+
i = 0
|
50
|
+
while 7 ** i < 1000 ** 22
|
51
|
+
Numerical.decode(Numerical.encode(7 ** i)).should == 7 ** i
|
52
|
+
i += 1
|
197
53
|
end
|
198
54
|
end
|
199
55
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: numerical
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -47,14 +47,21 @@ description: Bi-Directional conversion between english language numbers (e.g. '
|
|
47
47
|
hundred') and integers
|
48
48
|
email:
|
49
49
|
- contact@danielknell.co.uk
|
50
|
-
executables:
|
50
|
+
executables:
|
51
|
+
- numerical
|
51
52
|
extensions: []
|
52
53
|
extra_rdoc_files: []
|
53
54
|
files:
|
55
|
+
- lib/numerical/constants.rb
|
56
|
+
- lib/numerical/decoder.rb
|
57
|
+
- lib/numerical/encoder.rb
|
54
58
|
- lib/numerical/version.rb
|
55
59
|
- lib/numerical.rb
|
56
60
|
- LICENSE
|
57
61
|
- README.md
|
62
|
+
- bin/numerical
|
63
|
+
- spec/numerical/decoder_spec.rb
|
64
|
+
- spec/numerical/encoder_spec.rb
|
58
65
|
- spec/numerical_spec.rb
|
59
66
|
- spec/spec_helper.rb
|
60
67
|
homepage: http://github.com/artisanofcode/ruby-numerical
|
@@ -82,5 +89,7 @@ signing_key:
|
|
82
89
|
specification_version: 3
|
83
90
|
summary: English language number parsing and generation for ruby
|
84
91
|
test_files:
|
92
|
+
- spec/numerical/decoder_spec.rb
|
93
|
+
- spec/numerical/encoder_spec.rb
|
85
94
|
- spec/numerical_spec.rb
|
86
95
|
- spec/spec_helper.rb
|