numbers_in_words 0.2.0 → 0.5.1
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 +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +58 -0
- data/.travis.yml +15 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +50 -26
- data/README.md +20 -70
- data/Rakefile +3 -1
- data/bin/spec +2 -0
- data/lib/numbers_in_words.rb +49 -15
- data/lib/numbers_in_words/duck_punch.rb +12 -8
- 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 +34 -25
- 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 +78 -13
- data/lib/numbers_in_words/version.rb +3 -1
- data/lib/numbers_in_words/writer.rb +69 -0
- data/numbers_in_words.gemspec +15 -14
- 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 +12 -12
- data/spec/number_parser_spec.rb +31 -0
- data/spec/numbers_in_words_spec.rb +74 -54
- data/spec/numerical_strings_spec.rb +35 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/to_word_spec.rb +18 -0
- data/spec/words_in_numbers_spec.rb +135 -117
- data/spec/writer_spec.rb +26 -0
- data/spec/years_spec.rb +27 -0
- metadata +61 -59
- data/lib/numbers_in_words/english/constants.rb +0 -93
- data/lib/numbers_in_words/english/language_writer_english.rb +0 -107
- data/lib/numbers_in_words/language_writer.rb +0 -31
- data/lib/numbers_in_words/number_parser.rb +0 -81
- data/lib/numbers_in_words/to_number.rb +0 -82
- data/spec/language_writer_spec.rb +0 -23
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 71344514fae412865a50ec69a9b58335ac9249aadf29bd5145a8455f503473b0
|
4
|
+
data.tar.gz: 128abd6b5546902d819c11b9105d573a564e6e1679c84bbeb8910bb6f28c03f8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2cb8730bc67b4be3a3aba9a63e4198c1a2e11e9664879d9f859fc4cf11b26743671abb97d180d411cd6a2dfaa6309afadf9f2d61a584c6ef2d5b05ecbbbfab16
|
7
|
+
data.tar.gz: 1c50db96276a5a9a9211bdb460c1f9e686fb35436a180d0aaf8de34961061cfd400421680a227558642b124d9be88eaa9f5a67ff3dfbbf65e4ba8ebfed5293d1
|
data/.codeclimate.yml
ADDED
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# The behavior of RuboCop can be controlled via the .rubocop.yml
|
2
|
+
# configuration file. It makes it possible to enable/disable
|
3
|
+
# certain cops (checks) and to alter their behavior if they accept
|
4
|
+
# any parameters. The file can be placed either in your home
|
5
|
+
# directory or in some project directory.
|
6
|
+
#
|
7
|
+
# RuboCop will start looking for the configuration file in the directory
|
8
|
+
# where the inspected file is and continue its way up to the root directory.
|
9
|
+
#
|
10
|
+
# See https://docs.rubocop.org/rubocop/configuration
|
11
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
12
|
+
Enabled: true
|
13
|
+
Layout/SpaceAroundMethodCallOperator:
|
14
|
+
Enabled: true
|
15
|
+
Lint/DeprecatedOpenSSLConstant:
|
16
|
+
Enabled: true
|
17
|
+
Lint/MixedRegexpCaptureTypes:
|
18
|
+
Enabled: true
|
19
|
+
Lint/RaiseException:
|
20
|
+
Enabled: true
|
21
|
+
Lint/StructNewOverride:
|
22
|
+
Enabled: true
|
23
|
+
Style/ExponentialNotation:
|
24
|
+
Enabled: true
|
25
|
+
Style/HashEachMethods:
|
26
|
+
Enabled: true
|
27
|
+
Style/HashTransformKeys:
|
28
|
+
Enabled: true
|
29
|
+
Style/HashTransformValues:
|
30
|
+
Enabled: true
|
31
|
+
Style/RedundantFetchBlock:
|
32
|
+
Enabled: true
|
33
|
+
Style/RedundantRegexpCharacterClass:
|
34
|
+
Enabled: true
|
35
|
+
Style/RedundantRegexpEscape:
|
36
|
+
Enabled: true
|
37
|
+
Style/SlicingWithRange:
|
38
|
+
Enabled: true
|
39
|
+
Lint/DuplicateElsifCondition:
|
40
|
+
Enabled: true
|
41
|
+
Style/AccessorGrouping:
|
42
|
+
Enabled: true
|
43
|
+
Style/ArrayCoercion:
|
44
|
+
Enabled: true
|
45
|
+
Style/BisectedAttrAccessor:
|
46
|
+
Enabled: true
|
47
|
+
Style/CaseLikeIf:
|
48
|
+
Enabled: true
|
49
|
+
Style/Documentation:
|
50
|
+
Enabled: false
|
51
|
+
Style/HashAsLastArrayItem:
|
52
|
+
Enabled: true
|
53
|
+
Style/HashLikeCase:
|
54
|
+
Enabled: true
|
55
|
+
Style/RedundantAssignment:
|
56
|
+
Enabled: true
|
57
|
+
Style/RedundantFileExtensionInRequire:
|
58
|
+
Enabled: true
|
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
env:
|
2
|
+
global:
|
3
|
+
- CC_TEST_REPORTER_ID=9a548b48c1c0804d8fb9083ae8e9693a5d5197eb86e8cf1b63a89d18f33e0464
|
4
|
+
sudo: false
|
5
|
+
language: ruby
|
6
|
+
rvm:
|
7
|
+
- "2.6.6"
|
8
|
+
- "2.7.1"
|
9
|
+
before_script:
|
10
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
11
|
+
- chmod +x ./cc-test-reporter
|
12
|
+
- ./cc-test-reporter before-build
|
13
|
+
script: ./bin/spec
|
14
|
+
after_script:
|
15
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,39 +1,63 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
numbers_in_words (0.
|
5
|
-
activesupport
|
4
|
+
numbers_in_words (0.5.1)
|
6
5
|
|
7
6
|
GEM
|
8
7
|
remote: https://rubygems.org/
|
9
8
|
specs:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
rspec-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
9
|
+
ast (2.4.1)
|
10
|
+
byebug (11.1.3)
|
11
|
+
diff-lcs (1.4.4)
|
12
|
+
docile (1.3.2)
|
13
|
+
json (2.3.1)
|
14
|
+
parallel (1.19.2)
|
15
|
+
parser (2.7.1.4)
|
16
|
+
ast (~> 2.4.1)
|
17
|
+
rainbow (3.0.0)
|
18
|
+
regexp_parser (1.7.1)
|
19
|
+
rexml (3.2.4)
|
20
|
+
rspec (3.4.0)
|
21
|
+
rspec-core (~> 3.4.0)
|
22
|
+
rspec-expectations (~> 3.4.0)
|
23
|
+
rspec-mocks (~> 3.4.0)
|
24
|
+
rspec-core (3.4.4)
|
25
|
+
rspec-support (~> 3.4.0)
|
26
|
+
rspec-expectations (3.4.0)
|
27
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
+
rspec-support (~> 3.4.0)
|
29
|
+
rspec-mocks (3.4.1)
|
30
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
31
|
+
rspec-support (~> 3.4.0)
|
32
|
+
rspec-support (3.4.1)
|
33
|
+
rubocop (0.88.0)
|
34
|
+
parallel (~> 1.10)
|
35
|
+
parser (>= 2.7.1.1)
|
36
|
+
rainbow (>= 2.2.2, < 4.0)
|
37
|
+
regexp_parser (>= 1.7)
|
38
|
+
rexml
|
39
|
+
rubocop-ast (>= 0.1.0, < 1.0)
|
40
|
+
ruby-progressbar (~> 1.7)
|
41
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
42
|
+
rubocop-ast (0.1.0)
|
43
|
+
parser (>= 2.7.0.1)
|
44
|
+
ruby-progressbar (1.10.1)
|
45
|
+
simplecov (0.17.1)
|
46
|
+
docile (~> 1.1)
|
47
|
+
json (>= 1.8, < 3)
|
48
|
+
simplecov-html (~> 0.10.0)
|
49
|
+
simplecov-html (0.10.2)
|
50
|
+
unicode-display_width (1.7.0)
|
32
51
|
|
33
52
|
PLATFORMS
|
34
53
|
ruby
|
35
54
|
|
36
55
|
DEPENDENCIES
|
37
|
-
|
56
|
+
byebug
|
38
57
|
numbers_in_words!
|
39
|
-
rspec
|
58
|
+
rspec (~> 3.4.0)
|
59
|
+
rubocop
|
60
|
+
simplecov (< 0.18.0)
|
61
|
+
|
62
|
+
BUNDLED WITH
|
63
|
+
2.1.4
|
data/README.md
CHANGED
@@ -1,42 +1,37 @@
|
|
1
|
+
[![Build Status](http://img.shields.io/travis/markburns/numbers_in_words.svg)](https://travis-ci.org/markburns/numbers_in_words)
|
2
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/a51210488896b798af20/maintainability)](https://codeclimate.com/github/markburns/numbers_in_words/maintainability)
|
3
|
+
[![Test Coverage](https://api.codeclimate.com/v1/badges/a51210488896b798af20/test_coverage)](https://codeclimate.com/github/markburns/numbers_in_words/test_coverage)
|
4
|
+
[![Gem Version](http://img.shields.io/gem/v/numbers_in_words.svg)](https://rubygems.org/gems/numbers_in_words)
|
5
|
+
[![License](http://img.shields.io/:license-mit-blue.svg)](http://markburns.mit-license.org)
|
6
|
+
|
1
7
|
Installation
|
2
8
|
============
|
3
9
|
|
4
|
-
```
|
10
|
+
```ruby
|
5
11
|
gem 'numbers_in_words'
|
6
|
-
|
7
|
-
require 'numbers_in_words'
|
8
|
-
require 'numbers_in_words/duck_punch' #see why later
|
9
12
|
```
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
I'm going to hopefully preempt some support queries by predicting this will happen:
|
14
|
+
Usage
|
15
|
+
=========
|
15
16
|
|
16
|
-
|
17
|
+
```ruby
|
18
|
+
require 'numbers_in_words'
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
NoMethodError: undefined method `in_numbers' for "123":String
|
21
|
-
```
|
20
|
+
NumbersInWords.in_words(112)
|
21
|
+
#=> one hundred and twelve
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
NumbersInWords.in_numbers("one googol")
|
24
|
+
#=>10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
with:
|
26
|
+
NumbersInWords.in_numbers("Seventy million, five-hundred and fifty six thousand point eight nine three")
|
27
|
+
#=> 70556000.893
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
require 'numbers_in_words/duck_punch'
|
29
|
+
NumbersInWords.in_numbers("nineteen sixty five")
|
30
|
+
#=> 1965
|
33
31
|
```
|
34
32
|
|
35
|
-
Plus it now only adds a single `#in_words` method to `Numeric` and an `#in_numbers`
|
36
|
-
method to `String` instead of a whole bunch of them.
|
37
33
|
|
38
|
-
|
39
|
-
=========
|
34
|
+
Monkey patch version
|
40
35
|
|
41
36
|
```ruby
|
42
37
|
require 'numbers_in_words'
|
@@ -50,48 +45,3 @@ require 'numbers_in_words/duck_punch'
|
|
50
45
|
"Seventy million, five-hundred and fifty six thousand point eight nine three".in_numbers
|
51
46
|
#=> 70556000.893
|
52
47
|
```
|
53
|
-
|
54
|
-
---------------
|
55
|
-
|
56
|
-
Whilst creating this project I realized that in English:
|
57
|
-
|
58
|
-
* Numbers are grouped in groups of threes
|
59
|
-
* Numbers less than 1,000 are grouped by hundreds and then by tens
|
60
|
-
* There are specific rules for when we put an "and" in between numbers
|
61
|
-
|
62
|
-
It makes sense to manage the numbers by these groups, so
|
63
|
-
I created a method groups_of which will split any integer into
|
64
|
-
groups of a certain size. It returns a hash with the power of ten
|
65
|
-
as the key and the multiplier as the value. E.g:
|
66
|
-
|
67
|
-
```ruby
|
68
|
-
31245.groups_of(3)
|
69
|
-
#=> {0=>245,3=>31} #i.e. 31 thousands, and 245 ones
|
70
|
-
|
71
|
-
245.group_of(2)
|
72
|
-
#=> {0=>45,2=>2} #i.e. 2 hundreds, and 45 ones
|
73
|
-
```
|
74
|
-
|
75
|
-
(In Japanese numbers are grouped in groups of 4, so it makes sense to try and
|
76
|
-
separate the language related stuff from the number grouping related stuff)
|
77
|
-
|
78
|
-
Example of usage:
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
245.group_words(2,"English") do |power, name, digits|
|
82
|
-
puts "#{digits}*10^#{power} #{digits} #{name}s"
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
2 * 10^2 = 2 hundreds
|
87
|
-
45 * 10^0 = 45 ones
|
88
|
-
|
89
|
-
```
|
90
|
-
|
91
|
-
Future plans
|
92
|
-
============
|
93
|
-
|
94
|
-
* Handle complex numbers
|
95
|
-
* Option for outputting punctuation
|
96
|
-
* Reject invalid numbers
|
97
|
-
* Support for other languages
|
data/Rakefile
CHANGED
data/bin/spec
ADDED
data/lib/numbers_in_words.rb
CHANGED
@@ -1,24 +1,58 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require 'numbers_in_words/
|
5
|
-
|
6
|
-
require 'numbers_in_words/english/constants'
|
7
|
-
require 'numbers_in_words/english/language_writer_english'
|
8
|
-
|
9
|
-
require 'numbers_in_words/number_group'
|
10
|
-
require 'numbers_in_words/number_parser'
|
11
|
-
require 'numbers_in_words/to_number'
|
3
|
+
require 'numbers_in_words/version'
|
4
|
+
require 'numbers_in_words/exceptional_numbers'
|
5
|
+
require 'numbers_in_words/parsing/number_parser'
|
12
6
|
require 'numbers_in_words/to_word'
|
7
|
+
require 'numbers_in_words/parsing/to_number'
|
13
8
|
|
14
9
|
module NumbersInWords
|
15
|
-
LENGTH_OF_GOOGOL
|
10
|
+
LENGTH_OF_GOOGOL = 101 # length of the string i.e. one with 100 zeros
|
11
|
+
Error = ::Class.new(::StandardError)
|
12
|
+
AmbiguousParsingError = ::Class.new(Error)
|
13
|
+
DivideByZeroError = ::Class.new(Error)
|
14
|
+
InvalidNumber = ::Class.new(Error)
|
16
15
|
|
17
16
|
class << self
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
extend Forwardable
|
18
|
+
def_delegators :exceptional_numbers, :fraction
|
19
|
+
|
20
|
+
def in_words(num, fraction: false)
|
21
|
+
ToWord.new(num).in_words(fraction: fraction)
|
22
|
+
end
|
23
|
+
|
24
|
+
def in_numbers(words, only_compress: false)
|
25
|
+
ToNumber.new(words, only_compress).call
|
26
|
+
end
|
27
|
+
|
28
|
+
def exceptional_numbers
|
29
|
+
@exceptional_numbers ||= ExceptionalNumbers.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def lookup(number)
|
33
|
+
exceptional_numbers.lookup(number)
|
34
|
+
end
|
35
|
+
|
36
|
+
def exceptional_number(text)
|
37
|
+
exceptional_numbers_to_i[text]
|
38
|
+
end
|
39
|
+
|
40
|
+
def power_of_ten(text)
|
41
|
+
powers_of_ten_to_i[text]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def exceptional_numbers_to_i
|
47
|
+
@exceptional_numbers_to_i ||= swap_keys exceptional_numbers.to_h
|
48
|
+
end
|
49
|
+
|
50
|
+
def powers_of_ten_to_i
|
51
|
+
@powers_of_ten_to_i ||= swap_keys POWERS_OF_TEN
|
52
|
+
end
|
53
|
+
|
54
|
+
def swap_keys(hash)
|
55
|
+
hash.each_with_object({}) { |(k, v), h| h[v] = k }
|
21
56
|
end
|
22
57
|
end
|
23
58
|
end
|
24
|
-
|
@@ -1,19 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module NumbersInWords
|
2
|
-
|
3
|
-
|
4
|
+
module NumericExtension
|
5
|
+
def in_words(fraction: false)
|
6
|
+
NumbersInWords::ToWord.new(self).in_words(fraction: fraction)
|
7
|
+
end
|
4
8
|
end
|
5
|
-
end
|
6
9
|
|
7
|
-
module
|
8
|
-
|
9
|
-
|
10
|
+
module StringExtension
|
11
|
+
def in_numbers(only_compress: false)
|
12
|
+
NumbersInWords::ToNumber.new(self, only_compress).call
|
13
|
+
end
|
10
14
|
end
|
11
15
|
end
|
12
16
|
|
13
17
|
class String
|
14
|
-
include
|
18
|
+
include NumbersInWords::StringExtension
|
15
19
|
end
|
16
20
|
|
17
21
|
class Numeric
|
18
|
-
include NumbersInWords
|
22
|
+
include NumbersInWords::NumericExtension
|
19
23
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
require_relative 'fraction'
|
6
|
+
require_relative 'powers_of_ten'
|
7
|
+
|
8
|
+
module NumbersInWords
|
9
|
+
class ExceptionalNumbers
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
DEFINITIONS = {
|
13
|
+
0 => { number: 'zero', ordinal: 'zeroth' },
|
14
|
+
1 => { number: 'one', ordinal: 'first' },
|
15
|
+
2 => { number: 'two', ordinal: 'second', fraction: { singular: 'half', plural: 'halves' } },
|
16
|
+
3 => { number: 'three', ordinal: 'third' },
|
17
|
+
4 => { number: 'four', ordinal: 'fourth', fraction: { singular: 'quarter', plural: 'quarters' } },
|
18
|
+
5 => { number: 'five', ordinal: 'fifth' },
|
19
|
+
6 => { number: 'six' },
|
20
|
+
7 => { number: 'seven' },
|
21
|
+
8 => { number: 'eight', ordinal: 'eighth' },
|
22
|
+
9 => { number: 'nine', ordinal: 'ninth' },
|
23
|
+
10 => { number: 'ten' },
|
24
|
+
11 => { number: 'eleven' },
|
25
|
+
12 => { number: 'twelve', ordinal: 'twelfth' },
|
26
|
+
13 => { number: 'thirteen' },
|
27
|
+
14 => { number: 'fourteen' },
|
28
|
+
15 => { number: 'fifteen' },
|
29
|
+
16 => { number: 'sixteen' },
|
30
|
+
17 => { number: 'seventeen' },
|
31
|
+
18 => { number: 'eighteen' },
|
32
|
+
19 => { number: 'nineteen' },
|
33
|
+
20 => { number: 'twenty', ordinal: 'twentieth' },
|
34
|
+
30 => { number: 'thirty', ordinal: 'thirtieth' },
|
35
|
+
40 => { number: 'forty', ordinal: 'fortieth' },
|
36
|
+
50 => { number: 'fifty', ordinal: 'fiftieth' },
|
37
|
+
60 => { number: 'sixty', ordinal: 'sixtieth' },
|
38
|
+
70 => { number: 'seventy', ordinal: 'seventieth' },
|
39
|
+
80 => { number: 'eighty', ordinal: 'eightieth' },
|
40
|
+
90 => { number: 'ninety', ordinal: 'ninetieth' }
|
41
|
+
}.freeze
|
42
|
+
|
43
|
+
def fraction_names
|
44
|
+
@fraction_names ||= determine_fraction_names
|
45
|
+
end
|
46
|
+
|
47
|
+
def lookup_fraction(words)
|
48
|
+
fraction_lookup[words]
|
49
|
+
end
|
50
|
+
|
51
|
+
def fraction_lookup
|
52
|
+
@fraction_lookup ||= generate_fraction_lookup
|
53
|
+
end
|
54
|
+
|
55
|
+
def lookup(number)
|
56
|
+
to_h[number]
|
57
|
+
end
|
58
|
+
|
59
|
+
def fraction(denominator: nil, numerator: nil, word: nil)
|
60
|
+
raise unless denominator || word
|
61
|
+
|
62
|
+
numerator ||= 1
|
63
|
+
|
64
|
+
denominator ||= NumbersInWords.in_numbers(word)
|
65
|
+
|
66
|
+
Fraction.new(denominator: denominator, numerator: numerator, attributes: DEFINITIONS[denominator])
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_h
|
70
|
+
@to_h ||= DEFINITIONS.transform_values do |h|
|
71
|
+
h[:number]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def generate_fraction_lookup
|
78
|
+
named_fractions.each_with_object({}) do |f, result|
|
79
|
+
f.lookup_keys.each do |k|
|
80
|
+
key = k.split(' ').last
|
81
|
+
result[key] = 1.0 / f.denominator.to_f
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def named_fractions
|
87
|
+
@named_fractions ||= numbers.flat_map do |n|
|
88
|
+
[
|
89
|
+
Fraction.new(denominator: n, numerator: 1),
|
90
|
+
Fraction.new(denominator: n, numerator: 2)
|
91
|
+
]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def numbers
|
96
|
+
(2..100).to_a + powers_of_ten_skipping_googolplex.map { |p| 10**p }
|
97
|
+
end
|
98
|
+
|
99
|
+
def powers_of_ten_skipping_googolplex
|
100
|
+
POWERS_OF_TEN.keys[0..-2]
|
101
|
+
end
|
102
|
+
|
103
|
+
def determine_fraction_names
|
104
|
+
names = named_fractions.map(&:in_words)
|
105
|
+
|
106
|
+
words = names.map(&:split).map(&:last)
|
107
|
+
words += strip_punctuation(words)
|
108
|
+
words.uniq
|
109
|
+
end
|
110
|
+
|
111
|
+
def strip_punctuation(words)
|
112
|
+
words.map { |w| w.gsub(/^a-z/, ' ') }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|