num_words 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 21d205d24368e2f8f01249971360cd573497c2892cea31840289831937af26f0
4
- data.tar.gz: 5597dd4bc9baf0217b5bca0111dc2e214cae69838de05635ba53849ba72c017c
3
+ metadata.gz: 92bd9503909fd6d11da13baeccbe68e60c86505d1cb9aabc057ca704c962af4b
4
+ data.tar.gz: db689f477ab8a791fc8c09a648407b2edb3a2fa954a780034b6c5d1e2218fe10
5
5
  SHA512:
6
- metadata.gz: e4ff68ce798397ccea435a92976665940d8fe23a869a4dc34332318f81caf6ec81f3c85153349c52bc40bd52999fd557f709fff04c60e8c434aa3e7d4ce2661d
7
- data.tar.gz: f5cf56ac330f7de0d23ead06d6989e40ad461a85484adb044ad20c65fd493cc01f25aeb3df00bfbe2700955292844378615b43764849b3ae57c996b8a10bf111
6
+ metadata.gz: 98db3a1bcf32c42384c53cd990c83e37c22d1a0bb47ad91beecf0b96009051405e18c72cec3a35ec71de49bdd127aca44cf41fa2d34c78fdae5a6acbb82bde7d
7
+ data.tar.gz: 7df9d662a74480d9ae3f1b41a1153d5700726cf19f4f6572cf8e93c2224f4e90ab3f6490dd1411d70f339333cf09dd70dbc05795d4d773685a4a9e9ad521e992
@@ -0,0 +1,129 @@
1
+ # lib/num_words/converter.rb
2
+ # frozen_string_literal: true
3
+
4
+ module NumWords
5
+ ONES = %w[zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen].freeze
6
+ TENS = %w[zero ten twenty thirty forty fifty sixty seventy eighty ninety].freeze
7
+
8
+ AM_EXPONENTS = {
9
+ 3 => 'thousand', 6 => 'million', 9 => 'billion', 12 => 'trillion',
10
+ 15 => 'quadrillion', 18 => 'quintillion', 21 => 'sexillion', 24 => 'septillion',
11
+ 27 => 'octillion', 30 => 'nonillion', 33 => 'decillion', 36 => 'undecillion',
12
+ 39 => 'duodecillion', 42 => 'tredecillion', 45 => 'quattuordecillion', 48 => 'quindecillion',
13
+ 51 => 'sexdecillion', 54 => 'septendecillion', 57 => 'octodecillion', 60 => 'novemdecillion',
14
+ 63 => 'vigintillion', 66 => 'unvigintillion', 69 => 'duovigintillion'
15
+ }.freeze
16
+
17
+ EU_EXPONENTS = {
18
+ 3 => 'thousand', 6 => 'million', 9 => 'milliard', 12 => 'billion',
19
+ 15 => 'billiard', 18 => 'trillion', 21 => 'trilliard', 24 => 'quadrillion',
20
+ 27 => 'quadrilliard', 30 => 'quintillion', 33 => 'quintilliard', 36 => 'sextillion',
21
+ 39 => 'sextilliard', 42 => 'septillion', 45 => 'septilliard', 48 => 'octillion',
22
+ 51 => 'octilliard', 54 => 'noventillion', 57 => 'noventilliard', 60 => 'decillion',
23
+ 63 => 'decilliard', 66 => 'undecillion', 69 => 'undecilliard'
24
+ }.freeze
25
+
26
+ UK_EXPONENTS = {
27
+ 3 => 'thousand', 6 => 'million', 12 => 'billion', 15 => 'billiard',
28
+ 18 => 'trillion', 21 => 'trilliard', 24 => 'quadrillion'
29
+ }.freeze
30
+
31
+ FR_EXPONENTS = {
32
+ 3 => 'mille', 6 => 'million', 9 => 'milliard', 12 => 'billion',
33
+ 15 => 'billiard', 18 => 'trillion', 21 => 'trilliard'
34
+ }.freeze
35
+
36
+ INDIAN_UNITS = ['', 'thousand', 'lakh', 'crore'].freeze
37
+
38
+ COUNTRY_EXPONENTS = {
39
+ us: AM_EXPONENTS,
40
+ eu: EU_EXPONENTS,
41
+ uk: UK_EXPONENTS,
42
+ fr: FR_EXPONENTS,
43
+ in: INDIAN_UNITS
44
+ }.freeze
45
+
46
+ class << self
47
+ def to_words(number, country: :us, include_and: true)
48
+ return to_words_indian(number) if country == :in
49
+
50
+ val = number.to_i.abs
51
+ return 'zero' if val.zero?
52
+
53
+ exp_hash = COUNTRY_EXPONENTS[country] || AM_EXPONENTS
54
+ to_words_generic(val, exp_hash, include_and)
55
+ end
56
+
57
+ def to_words_indian(num)
58
+ integer_part, decimal_part = num.to_s.split('.')
59
+ integer_words = indian_units_to_words(integer_part.to_i)
60
+ return integer_words if decimal_part.nil? || decimal_part.to_i.zero?
61
+
62
+ decimal_words = decimal_part.chars.map { |d| sub_thousand_to_words(d.to_i) }.join(' ')
63
+ "#{integer_words} and #{decimal_words}"
64
+ end
65
+
66
+ private
67
+
68
+ def to_words_generic(val, exp_hash, include_and)
69
+ chunks = []
70
+ while val.positive?
71
+ chunks << val % 1000
72
+ val /= 1000
73
+ end
74
+
75
+ result = []
76
+ chunks.each_with_index do |chunk, index|
77
+ next if chunk.zero?
78
+ words = hundreds_to_words(chunk, include_and && index.zero?)
79
+ result.unshift("#{words} #{exp_hash[index * 3]}".strip)
80
+ end
81
+ result.join(' ').strip
82
+ end
83
+
84
+ def hundreds_to_words(val, include_and = false)
85
+ return '' if val.zero?
86
+
87
+ words = []
88
+ if val >= 100
89
+ words << "#{ONES[val / 100]} hundred"
90
+ val %= 100
91
+ words << 'and' if val.positive? && include_and
92
+ end
93
+
94
+ words << TENS[val / 10] if val >= 20
95
+ val %= 10 if val >= 20
96
+ words << ONES[val] if val.positive?
97
+ words.join(' ').strip
98
+ end
99
+
100
+ def indian_units_to_words(num)
101
+ num = num.to_i
102
+ return 'zero' if num.zero?
103
+ words = []
104
+ unit_index = 0
105
+
106
+ loop do
107
+ break if num.zero?
108
+
109
+ num, remainder = unit_index.zero? ? num.divmod(1000) : num.divmod(100)
110
+ words.unshift("#{sub_thousand_to_words(remainder)} #{INDIAN_UNITS[unit_index]}".strip) if remainder.positive?
111
+ unit_index += 1
112
+ end
113
+
114
+ words.join(' ').strip
115
+ end
116
+
117
+ def sub_thousand_to_words(num)
118
+ num = num.to_i
119
+ return ONES[num] if num < 20
120
+ return "#{ONES[num / 100]} hundred" if num >= 100 && (num % 100).zero?
121
+
122
+ if num < 100
123
+ "#{TENS[num / 10]} #{ONES[num % 10]}".strip
124
+ else
125
+ "#{ONES[num / 100]} hundred and #{sub_thousand_to_words(num % 100)}"
126
+ end
127
+ end
128
+ end
129
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NumWords
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/num_words.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "num_words/version"
4
+ require_relative "num_words/converter"
4
5
 
5
6
  module NumWords
6
7
  class Error < StandardError; end
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: num_words
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mrmalvi
@@ -22,7 +22,9 @@ files:
22
22
  - Rakefile
23
23
  - exe/num_words
24
24
  - lib/num_words.rb
25
+ - lib/num_words/converter.rb
25
26
  - lib/num_words/version.rb
27
+ - num_words-0.1.0.gem
26
28
  - sig/num_words.rbs
27
29
  homepage: https://github.com/mrmalvi/num_words
28
30
  licenses: []