numbers_in_words 0.1.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +14 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +58 -0
- data/.travis.yml +15 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +47 -0
- data/Rakefile +2 -43
- data/bin/spec +2 -0
- data/lib/numbers_in_words.rb +55 -4
- data/lib/numbers_in_words/duck_punch.rb +23 -0
- data/lib/numbers_in_words/exceptional_numbers.rb +115 -0
- data/lib/numbers_in_words/fraction.rb +136 -0
- data/lib/numbers_in_words/number_group.rb +64 -0
- data/lib/numbers_in_words/parsing/fraction_parsing.rb +34 -0
- data/lib/numbers_in_words/parsing/number_parser.rb +98 -0
- data/lib/numbers_in_words/parsing/pair_parsing.rb +64 -0
- data/lib/numbers_in_words/parsing/parse_fractions.rb +45 -0
- data/lib/numbers_in_words/parsing/parse_individual_number.rb +68 -0
- data/lib/numbers_in_words/parsing/parse_status.rb +17 -0
- data/lib/numbers_in_words/parsing/special.rb +67 -0
- data/lib/numbers_in_words/parsing/to_number.rb +77 -0
- data/lib/numbers_in_words/powers_of_ten.rb +49 -0
- data/lib/numbers_in_words/to_word.rb +84 -0
- data/lib/numbers_in_words/version.rb +5 -0
- data/lib/numbers_in_words/writer.rb +69 -0
- data/numbers_in_words.gemspec +20 -27
- data/spec/exceptional_numbers_spec.rb +26 -0
- data/spec/fraction_spec.rb +152 -0
- data/spec/fractions_spec.rb +31 -0
- data/spec/non_monkey_patch_spec.rb +51 -0
- data/spec/number_group_spec.rb +17 -0
- data/spec/number_parser_spec.rb +31 -0
- data/spec/numbers_in_words_spec.rb +69 -83
- data/spec/numerical_strings_spec.rb +35 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/to_word_spec.rb +18 -0
- data/spec/words_in_numbers_spec.rb +137 -119
- data/spec/writer_spec.rb +26 -0
- data/spec/years_spec.rb +27 -0
- metadata +95 -45
- data/CHANGELOG +0 -1
- data/Manifest +0 -11
- data/README +0 -84
- data/examples/display_numbers_in_words.rb +0 -22
- data/init.rb +0 -8
- data/lib/numbers.rb +0 -260
- data/lib/words.rb +0 -221
data/CHANGELOG
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
v0.1.0. Handles decimals
|
data/Manifest
DELETED
data/README
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
Installation
|
2
|
-
============
|
3
|
-
|
4
|
-
gem install numbers_in_words
|
5
|
-
|
6
|
-
or
|
7
|
-
|
8
|
-
sudo gem install numbers_in_words
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
The file numbers_to_words defines a module NumbersToWords which is included in Fixnum and Bignum.
|
14
|
-
The in_words method can then be used on any Fixnum or Bignum object.
|
15
|
-
|
16
|
-
E.g.
|
17
|
-
>require 'numbers_in_words'
|
18
|
-
>112.in_words
|
19
|
-
=> one hundred and twelve
|
20
|
-
>"one googol".in_numbers
|
21
|
-
=>10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
22
|
-
>"Seventy million, five-hundred and fifty six thousand point eight nine three".in_numbers
|
23
|
-
=> 70556000.893
|
24
|
-
|
25
|
-
---------------
|
26
|
-
Example program
|
27
|
-
|
28
|
-
To try it out the program display_numbers_to_words.rb expects two integer parameters to define a
|
29
|
-
range. It then prints out all numbers in words included in this range.
|
30
|
-
|
31
|
-
e.g.
|
32
|
-
|
33
|
-
>ruby display_numbers_to_words.rb 1 11
|
34
|
-
one
|
35
|
-
two
|
36
|
-
three
|
37
|
-
four
|
38
|
-
five
|
39
|
-
six
|
40
|
-
seven
|
41
|
-
eight
|
42
|
-
nine
|
43
|
-
ten
|
44
|
-
eleven
|
45
|
-
|
46
|
-
Whilst creating this project I realized that in English:
|
47
|
-
|
48
|
-
* Numbers are grouped in groups of threes
|
49
|
-
* Numbers less than 1,000 are grouped by hundreds and then by tens
|
50
|
-
* There are specific rules for when we put an "and" in between numbers
|
51
|
-
|
52
|
-
It makes sense to manage the numbers by these groups, so
|
53
|
-
I created a method groups_of which will split any integer into
|
54
|
-
groups of a certain size. It returns a hash with the power of ten
|
55
|
-
as the key and the multiplier as the value. E.g:
|
56
|
-
|
57
|
-
> 31245.groups_of(3)
|
58
|
-
#=>
|
59
|
-
{0=>245,3=>31} #i.e. 31 thousands, and 245 ones
|
60
|
-
|
61
|
-
> 245.group_of(2)
|
62
|
-
#=>
|
63
|
-
{0=>45,2=>2} #i.e. 2 hundreds, and 45 ones
|
64
|
-
|
65
|
-
I also created a method group_words takes a block and a size parameter
|
66
|
-
This method which could be used by different languages.
|
67
|
-
(In Japanese numbers are grouped in groups of 4, so it makes sense to try and
|
68
|
-
separate the language related stuff from the number grouping related stuff)
|
69
|
-
|
70
|
-
Example of usage:
|
71
|
-
245.group_words(2,"English") do |power, name, digits|
|
72
|
-
puts "#{digits}*10^#{power} #{digits} #{name}s"
|
73
|
-
end
|
74
|
-
|
75
|
-
2*10^2= 2 hundreds
|
76
|
-
45*10^0 = 45 ones
|
77
|
-
|
78
|
-
Future plans
|
79
|
-
============
|
80
|
-
|
81
|
-
* Handle complex numbers
|
82
|
-
* Option for outputting punctuation
|
83
|
-
* Reject invalid numbers
|
84
|
-
* Support for other languages
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'numbers_in_words'
|
3
|
-
def usage code=-1
|
4
|
-
puts "\nUsage:\n\nruby #{__FILE__} <start> <end>"
|
5
|
-
exit code
|
6
|
-
end
|
7
|
-
if ARGV.length != 2
|
8
|
-
|
9
|
-
puts "Start and end arguments expected"
|
10
|
-
usage -1
|
11
|
-
end
|
12
|
-
start_number = ARGV[0].to_i
|
13
|
-
end_number = ARGV[1].to_i
|
14
|
-
|
15
|
-
if start_number > end_number
|
16
|
-
puts "Start number must be less than or equal to the end number"
|
17
|
-
usage -2
|
18
|
-
end
|
19
|
-
|
20
|
-
for i in start_number..end_number do
|
21
|
-
puts i.in_words
|
22
|
-
end
|
data/init.rb
DELETED
data/lib/numbers.rb
DELETED
@@ -1,260 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'active_support/core_ext/array'
|
3
|
-
module NumbersInWords
|
4
|
-
EXCEPTIONS = {
|
5
|
-
10 => "ten",
|
6
|
-
11 => "eleven",
|
7
|
-
12 => "twelve",
|
8
|
-
|
9
|
-
13 => "thirteen",
|
10
|
-
14 => "fourteen",
|
11
|
-
15 => "fifteen",
|
12
|
-
16 => "sixteen" ,
|
13
|
-
17 => "seventeen",
|
14
|
-
18 => "eighteen",
|
15
|
-
19 => "nineteen",
|
16
|
-
|
17
|
-
20 => "twenty",
|
18
|
-
30 => "thirty",
|
19
|
-
40 => "forty",
|
20
|
-
50 => "fifty",
|
21
|
-
60 => "sixty",
|
22
|
-
70 => "seventy",
|
23
|
-
80 => "eighty",
|
24
|
-
90 => "ninety"
|
25
|
-
}
|
26
|
-
|
27
|
-
DIGITS = %w[zero one two three four five six seven eight nine]
|
28
|
-
|
29
|
-
POWERS_OF_TEN ={
|
30
|
-
0 => "one",
|
31
|
-
1 => "ten",
|
32
|
-
2 => "hundred",
|
33
|
-
3 => "thousand",
|
34
|
-
6 => "million",
|
35
|
-
9 => "billion",
|
36
|
-
12 => "trillion",
|
37
|
-
15 => "quadrillion",
|
38
|
-
18 => "quintillion",
|
39
|
-
21 => "sextillion",
|
40
|
-
24 => "septillion",
|
41
|
-
27 => "octillion",
|
42
|
-
30 => "nonillion",
|
43
|
-
33 => "decillion",
|
44
|
-
36 => "undecillion",
|
45
|
-
39 => "duodecillion",
|
46
|
-
42 => "tredecillion",
|
47
|
-
45 => "quattuordecillion",
|
48
|
-
48 => "quindecillion",
|
49
|
-
51 => "sexdecillion",
|
50
|
-
54 => "septendecillion",
|
51
|
-
57 => "octodecillion",
|
52
|
-
60 => "novemdecillion",
|
53
|
-
63 => "vigintillion",
|
54
|
-
66 => "unvigintillion",
|
55
|
-
69 => "duovigintillion",
|
56
|
-
72 => "trevigintillion",
|
57
|
-
75 => "quattuorvigintillion",
|
58
|
-
78 => "quinvigintillion",
|
59
|
-
81 => "sexvigintillion",
|
60
|
-
84 => "septenvigintillion",
|
61
|
-
87 => "octovigintillion",
|
62
|
-
90 => "novemvigintillion",
|
63
|
-
93 => "trigintillion",
|
64
|
-
96 => "untrigintillion",
|
65
|
-
99 => "duotrigintillion",
|
66
|
-
100 => "googol"
|
67
|
-
}
|
68
|
-
|
69
|
-
LENGTH_OF_GOOGOL = 101 #length of the string i.e. one with 100 zeros
|
70
|
-
|
71
|
-
def in_words language="English"
|
72
|
-
case language
|
73
|
-
when "English" #allow for I18n
|
74
|
-
in_english
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def in_english
|
79
|
-
#handle 0-9
|
80
|
-
return DIGITS[self] if self.is_a?(Integer) and (0..9).to_a.include? self
|
81
|
-
#teens etc
|
82
|
-
return EXCEPTIONS[self] if self.is_a?(Integer) and EXCEPTIONS[self]
|
83
|
-
|
84
|
-
writer = LanguageWriterEnglish.new(self)
|
85
|
-
|
86
|
-
in_decimals = writer.decimals
|
87
|
-
return in_decimals unless in_decimals.nil?
|
88
|
-
|
89
|
-
number = to_i
|
90
|
-
|
91
|
-
return writer.negative() if number < 0
|
92
|
-
|
93
|
-
length = number.to_s.length
|
94
|
-
output = ""
|
95
|
-
|
96
|
-
if length == 2 #20-99
|
97
|
-
tens = (number/10).round*10 #write the tens
|
98
|
-
|
99
|
-
output << EXCEPTIONS[tens] # e.g. eighty
|
100
|
-
|
101
|
-
digit = number - tens #write the digits
|
102
|
-
|
103
|
-
output << " " + digit.in_english unless digit==0
|
104
|
-
else
|
105
|
-
output << writer.write() #longer numbers
|
106
|
-
end
|
107
|
-
|
108
|
-
output.strip
|
109
|
-
end
|
110
|
-
|
111
|
-
protected
|
112
|
-
|
113
|
-
class LanguageWriter
|
114
|
-
attr_accessor :number
|
115
|
-
|
116
|
-
def initialize number
|
117
|
-
@number = number
|
118
|
-
end
|
119
|
-
|
120
|
-
def group_words size
|
121
|
-
#1000 and over Numbers are split into groups of three
|
122
|
-
groups = NumberGroup.groups_of @number, size
|
123
|
-
powers = groups.keys.sort.reverse #put in descending order
|
124
|
-
|
125
|
-
powers.each do |power|
|
126
|
-
name = POWERS_OF_TEN[power]
|
127
|
-
digits = groups[power]
|
128
|
-
yield power, name, digits
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
class LanguageWriterEnglish < LanguageWriter
|
134
|
-
def negative
|
135
|
-
"minus " + (-@number).in_english
|
136
|
-
end
|
137
|
-
|
138
|
-
def write
|
139
|
-
length = @number.to_s.length
|
140
|
-
output = if length == 3
|
141
|
-
#e.g. 113 splits into "one hundred" and "thirteen"
|
142
|
-
write_groups(2)
|
143
|
-
|
144
|
-
#more than one hundred less than one googol
|
145
|
-
elsif length < LENGTH_OF_GOOGOL
|
146
|
-
write_groups(3)
|
147
|
-
|
148
|
-
elsif length >= LENGTH_OF_GOOGOL
|
149
|
-
write_googols
|
150
|
-
|
151
|
-
end
|
152
|
-
output.strip
|
153
|
-
end
|
154
|
-
|
155
|
-
def decimals
|
156
|
-
int, decimals = NumberGroup.new(@number).split_decimals
|
157
|
-
if int
|
158
|
-
out = int.in_english + " point "
|
159
|
-
decimals.each do |decimal|
|
160
|
-
out << decimal.to_i.in_english + " "
|
161
|
-
end
|
162
|
-
out.strip
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
private
|
167
|
-
def write_googols
|
168
|
-
googols, remainder = NumberGroup.new(@number).split_googols
|
169
|
-
output = ""
|
170
|
-
output << " " + googols.in_words + " googol"
|
171
|
-
if remainder > 0
|
172
|
-
prefix = " "
|
173
|
-
prefix << "and " if remainder < 100
|
174
|
-
output << prefix + remainder.in_english
|
175
|
-
end
|
176
|
-
output
|
177
|
-
end
|
178
|
-
|
179
|
-
def write_groups group
|
180
|
-
#e.g. 113 splits into "one hundred" and "thirteen"
|
181
|
-
output = ""
|
182
|
-
group_words(group) do |power, name, digits|
|
183
|
-
if digits > 0
|
184
|
-
prefix = " "
|
185
|
-
#no and between thousands and hundreds
|
186
|
-
prefix << "and " if power == 0 and digits < 100
|
187
|
-
output << prefix + digits.in_english
|
188
|
-
output << prefix + name unless power == 0
|
189
|
-
end
|
190
|
-
end
|
191
|
-
output
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
class NumberGroup
|
196
|
-
include Enumerable
|
197
|
-
attr_accessor :number
|
198
|
-
|
199
|
-
def each
|
200
|
-
@array.each { |item| yield item}
|
201
|
-
end
|
202
|
-
|
203
|
-
#split into groups this gives us 1234567 => 123 456 7
|
204
|
-
#so we need to reverse first
|
205
|
-
#in stages
|
206
|
-
def initialize number
|
207
|
-
@number = number
|
208
|
-
end
|
209
|
-
|
210
|
-
def groups size
|
211
|
-
#i.e. 1234567 => 7654321
|
212
|
-
groups = @number.to_s.reverse
|
213
|
-
#7654321 => 765 432 1
|
214
|
-
@array = groups.split("").in_groups_of(size)
|
215
|
-
#765 432 1 => 1 432 765
|
216
|
-
@array.reverse!
|
217
|
-
#1 432 765 => 1 234 567
|
218
|
-
#and turn back into integers
|
219
|
-
@array.map! {|group| group.reverse.join("").to_i}
|
220
|
-
@array.reverse! # put in ascending order of power of ten
|
221
|
-
power = 0
|
222
|
-
output = @array.inject({}) do |output, digits|
|
223
|
-
output[power] = digits
|
224
|
-
power += size
|
225
|
-
output
|
226
|
-
end
|
227
|
-
output
|
228
|
-
end
|
229
|
-
|
230
|
-
def split_decimals
|
231
|
-
if @number.is_a? Float
|
232
|
-
int = @number.to_i
|
233
|
-
decimal = @number - int
|
234
|
-
decimal = decimal.to_s.split(".")[1]
|
235
|
-
digits = decimal.split //
|
236
|
-
#convert to integers array
|
237
|
-
digits.inject([]) {|out, digit|
|
238
|
-
out<< digit.to_i
|
239
|
-
}
|
240
|
-
return int, digits
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
def self.groups_of number, size
|
245
|
-
new(number).groups(size)
|
246
|
-
end
|
247
|
-
|
248
|
-
def split_googols
|
249
|
-
output = ""
|
250
|
-
googols = @number.to_s[0 .. (-LENGTH_OF_GOOGOL)].to_i
|
251
|
-
remainder = @number.to_s[(1-LENGTH_OF_GOOGOL) .. -1].to_i
|
252
|
-
return googols, remainder
|
253
|
-
end
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
|
258
|
-
class Numeric
|
259
|
-
include NumbersInWords
|
260
|
-
end
|
data/lib/words.rb
DELETED
@@ -1,221 +0,0 @@
|
|
1
|
-
module WordsInNumbers
|
2
|
-
def in_numbers
|
3
|
-
text = to_s
|
4
|
-
|
5
|
-
WordToNumber.new.instance_eval do
|
6
|
-
text = strip_punctuation text
|
7
|
-
#negative numbers
|
8
|
-
return -1 * (text.gsub(/^minus /, "")).in_numbers if text =~ /^minus /
|
9
|
-
|
10
|
-
#easy single word case
|
11
|
-
word = word_to_integer(text)
|
12
|
-
return word unless word.nil?
|
13
|
-
|
14
|
-
#decimals
|
15
|
-
match = text.match(/\spoint\s/)
|
16
|
-
if match
|
17
|
-
integer = match.pre_match.in_numbers
|
18
|
-
|
19
|
-
decimal = decimal_portion match.post_match
|
20
|
-
|
21
|
-
return integer + decimal
|
22
|
-
end
|
23
|
-
|
24
|
-
#multiple word case
|
25
|
-
words = text.split " "
|
26
|
-
integers = word_array_to_integers words
|
27
|
-
|
28
|
-
integer= parse_numbers(integers)
|
29
|
-
return integer unless integer.nil?
|
30
|
-
return nil
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class WordToNumber
|
35
|
-
DIGITS= %w[zero one two three four five six seven eight nine]
|
36
|
-
|
37
|
-
EXCEPTIONS = {
|
38
|
-
"ten" => 10,
|
39
|
-
"eleven" => 11,
|
40
|
-
"twelve" => 12,
|
41
|
-
"thirteen" => 13,
|
42
|
-
"fourteen" => 14,
|
43
|
-
"fifteen" => 15,
|
44
|
-
"sixteen" => 16,
|
45
|
-
"seventeen" => 17,
|
46
|
-
"eighteen" => 18,
|
47
|
-
"nineteen" => 19,
|
48
|
-
"twenty" => 20,
|
49
|
-
"thirty" => 30,
|
50
|
-
"forty" => 40,
|
51
|
-
"fifty" => 50,
|
52
|
-
"sixty" => 60,
|
53
|
-
"seventy" => 70,
|
54
|
-
"eighty" => 80,
|
55
|
-
"ninety" => 90
|
56
|
-
}
|
57
|
-
|
58
|
-
|
59
|
-
POWERS_OF_TEN ={
|
60
|
-
"one" => 0,
|
61
|
-
"ten" => 1 ,
|
62
|
-
"hundred" => 2,
|
63
|
-
"thousand" => 3 ,
|
64
|
-
"million" => 6,
|
65
|
-
"billion" => 9,
|
66
|
-
"trillion" => 12,
|
67
|
-
"quadrillion" => 15,
|
68
|
-
"quintillion" => 18,
|
69
|
-
"sextillion" => 21,
|
70
|
-
"septillion" => 24,
|
71
|
-
"octillion" => 27,
|
72
|
-
"nonillion" => 30,
|
73
|
-
"decillion" => 33,
|
74
|
-
"undecillion" => 36,
|
75
|
-
"duodecillion" => 39,
|
76
|
-
"tredecillion" => 42,
|
77
|
-
"quattuordecillion" => 45,
|
78
|
-
"quindecillion" => 48,
|
79
|
-
"sexdecillion" => 51,
|
80
|
-
"septendecillion" => 54,
|
81
|
-
"octodecillion" => 57,
|
82
|
-
"novemdecillion" => 60,
|
83
|
-
"vigintillion" => 63,
|
84
|
-
"unvigintillion" => 66,
|
85
|
-
"duovigintillion" => 69,
|
86
|
-
"trevigintillion" => 72,
|
87
|
-
"quattuorvigintillion" => 75,
|
88
|
-
"quinvigintillion" => 78,
|
89
|
-
"sexvigintillion" => 81,
|
90
|
-
"septenvigintillion" => 84,
|
91
|
-
"octovigintillion" => 87,
|
92
|
-
"novemvigintillion" => 90,
|
93
|
-
"trigintillion" => 93,
|
94
|
-
"untrigintillion" => 96,
|
95
|
-
"duotrigintillion" => 99,
|
96
|
-
"googol" => 100
|
97
|
-
}
|
98
|
-
|
99
|
-
def strip_punctuation text
|
100
|
-
text = text.downcase.gsub /[^a-z ]/, " "
|
101
|
-
to_remove = true
|
102
|
-
|
103
|
-
to_remove = text.gsub! " ", " " while to_remove
|
104
|
-
|
105
|
-
text
|
106
|
-
end
|
107
|
-
|
108
|
-
def decimal_portion text
|
109
|
-
words = text.split " "
|
110
|
-
integers = word_array_to_integers words
|
111
|
-
decimal = "0." + integers.join()
|
112
|
-
decimal.to_f
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
private
|
117
|
-
|
118
|
-
# Example: 364,895,457,898
|
119
|
-
#three hundred and sixty four billion eight hundred and ninety five million
|
120
|
-
#four hundred and fifty seven thousand eight hundred and ninety eight
|
121
|
-
#
|
122
|
-
#3 100 60 4 10^9, 8 100 90 5 10^6, 4 100 50 7 1000, 8 100 90 8
|
123
|
-
# memory answer
|
124
|
-
#x1. 3 add to memory because answer and memory are zero 3 0
|
125
|
-
#x2. memory * 100 (because memory<100) 300 0
|
126
|
-
#x3. 60 add to memory because memory > 60 360 0
|
127
|
-
#x3. 4 add to memory because memory > 4 364 0
|
128
|
-
#x4. multiply memory by 10^9 because memory < power of ten 364*10^9 0
|
129
|
-
#x5. add memory to answer (and reset)memory > 8 (memory pow of ten > 2) 0 364*10^9
|
130
|
-
#x6. 8 add to memory because not finished 8 ''
|
131
|
-
#x7. multiply memory by 100 because memory < 100 800 ''
|
132
|
-
#x8. add 90 to memory because memory > 90 890 ''
|
133
|
-
#x9. add 5 to memory because memory > 5 895 ''
|
134
|
-
#x10. multiply memory by 10^6 because memory < power of ten 895*10^6 ''
|
135
|
-
#x11. add memory to answer (and reset) because memory power ten > 2 0 364895 * 10^6
|
136
|
-
#x12. 4 add to memory because not finished 4 ''
|
137
|
-
#x13. memory * 100 because memory < 100 400 ''
|
138
|
-
#x14. memory + 50 because memory > 50 450 ''
|
139
|
-
#x15. memory + 7 because memory > 7 457 ''
|
140
|
-
#x16. memory * 1000 because memory < 1000 457000 ''
|
141
|
-
#x17. add memory to answer (and reset)memory > 8 (memory pow of ten > 2) 0 364895457000
|
142
|
-
#x18. 8 add to memory because not finished 8 ''
|
143
|
-
#x19. memory * 100 because memory < 100 800 ''
|
144
|
-
#x14. memory + 90 because memory > 90 890 ''
|
145
|
-
#x15. memory + 8 because memory > 8 898 ''
|
146
|
-
#16. finished so add memory to answer
|
147
|
-
|
148
|
-
#Example
|
149
|
-
#2001
|
150
|
-
#two thousand and one
|
151
|
-
#2 1000 1
|
152
|
-
# memory answer
|
153
|
-
#1. add 2 to memory because first 2 0
|
154
|
-
#2. multiply memory by 1000 because memory < 1000 2000 0
|
155
|
-
#3. add memory to answer,reset, because power of ten>2 0 2000
|
156
|
-
#4. add 1 to memory 1 2000
|
157
|
-
#5. finish - add memory to answer 0 2001
|
158
|
-
def parse_numbers(integers)
|
159
|
-
memory = 0
|
160
|
-
answer = 0
|
161
|
-
reset = true #reset each time memory is reset
|
162
|
-
integers.each_with_index do |integer, index|
|
163
|
-
if reset
|
164
|
-
reset = false
|
165
|
-
memory += integer
|
166
|
-
else
|
167
|
-
#x4. multiply memory by 10^9 because memory < power of ten
|
168
|
-
if is_power_of_ten?(integer)
|
169
|
-
if power_of_ten(integer)> 2
|
170
|
-
memory *= integer
|
171
|
-
#17. add memory to answer (and reset) (memory pow of ten > 2)
|
172
|
-
answer += memory
|
173
|
-
memory = 0
|
174
|
-
reset = true
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
if memory < integer
|
179
|
-
memory *= integer
|
180
|
-
else
|
181
|
-
memory += integer
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
answer += memory
|
186
|
-
end
|
187
|
-
|
188
|
-
def power_of_ten integer
|
189
|
-
Math.log10(integer)
|
190
|
-
end
|
191
|
-
|
192
|
-
def is_power_of_ten? integer
|
193
|
-
power_of_ten(integer)==power_of_ten(integer).to_i
|
194
|
-
end
|
195
|
-
|
196
|
-
#handles simple single word numbers
|
197
|
-
#e.g. one, seven, twenty, eight, thousand etc
|
198
|
-
def word_to_integer word
|
199
|
-
text = word.to_s.chomp.strip
|
200
|
-
#digits 0-9
|
201
|
-
digit = DIGITS.index(text)
|
202
|
-
return digit unless digit.nil?
|
203
|
-
|
204
|
-
#digits which are exceptions
|
205
|
-
exception = EXCEPTIONS[text]
|
206
|
-
return exception unless exception.nil?
|
207
|
-
|
208
|
-
power = POWERS_OF_TEN[text]
|
209
|
-
return 10**power unless power.nil?
|
210
|
-
end
|
211
|
-
|
212
|
-
def word_array_to_integers words
|
213
|
-
words.map { |i| word_to_integer i }.compact
|
214
|
-
end
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
class String
|
219
|
-
include WordsInNumbers
|
220
|
-
end
|
221
|
-
|