cousin_roman 1.0.4 → 1.0.5

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
  SHA1:
3
- metadata.gz: 3a8b6dfc559930d66a36f9cf48fee854d3b9a34e
4
- data.tar.gz: 6cc9bd2645c0c136e4553de3d68a2263056c4b11
3
+ metadata.gz: ec3fa2cc7d9e4ab2b07e528b54976fb4133a8b92
4
+ data.tar.gz: 9bdac0d47492a5a17cc9eee724a856364987e67c
5
5
  SHA512:
6
- metadata.gz: 37d624ab76834dbfb7de0d3aaac9c68cf0c52e6feb094b1eddb224e5d9bbc193e31d2a4014ebe83dc9976218d09daef7cf16f1305d60a858ae01fc32a6a75f1a
7
- data.tar.gz: af80ee0573e5013fbc7b9698e8472cae0215b6a762e9e15c9d129e9ff2b9714f9f0ac3b1c69521fcba1a2d3d5d95cdf824c5c76023cf773254af585da14fed22
6
+ metadata.gz: 5bebb3279b63fdca8189a5c1290a7ebb4baeb76abf42e88081e19614dc8bd7d386d8c70aefc7c416e91386566be700f96b0e17144d83469e8e4e043b64b6aa89
7
+ data.tar.gz: f6834054b705eb3e16f7aeb9b93f01c90b2622cf7dc88524570a4fa02d4ccb779a49bcb0bdb028fcdcaea8d220d9b43a1de3eac088958f7a9d757ba815b6ea12
data/README.md CHANGED
@@ -1,9 +1,23 @@
1
1
  # CousinRoman
2
2
 
3
- `CousinRoman` provides functionality to convert between Roman and Arabian numerals.
4
-
3
+ CousinRoman provides functionality to convert between Roman and Arabian numerals.
5
4
  The functionality provided via String and Integer extensions.
6
5
 
6
+ ## Roman numbers and conversion rules
7
+
8
+ CousinRoman follows strict roman notation with subtractive rule, i.e.
9
+
10
+ 1. Letters should be ordered by decreasing of magnitude.
11
+ 2. Only I, X, C, M can be repeated, but up to three times.
12
+ 3. Letter with lower magnitude can appear BEFORE letter with higher magnitude,
13
+ but only in the following cases: IV, IX, XL, XC, CD, CM - lets call them **subtractives**
14
+ 4. **subtractives** and regular letters cannot appear within the same power,
15
+ i.e. `ivi` is not allowed.
16
+
17
+ Therefore, only numbers within range of 1..3999 can be represented in roman notation.
18
+
19
+ CousinRoman is thoroughly spec'ed, and considered reliable in following these rules.
20
+
7
21
  ## Installation
8
22
 
9
23
  Add this line to your application's Gemfile:
@@ -38,6 +52,10 @@ For example:
38
52
  '100500'.to_roman! # => TypeError: not a valid roman number
39
53
  ```
40
54
 
55
+ `String#to_arabian(!)` is case insensitive.
56
+
57
+ `Integer#to_roman(!)` returns numerals in upper case.
58
+
41
59
  ## Testing
42
60
 
43
61
  Just run
@@ -28,14 +28,14 @@ module CousinRoman
28
28
  end
29
29
 
30
30
  def build_roman(thousands, hundreds, tens, ones)
31
- build_pow(thousands, 4) +
32
- build_pow(hundreds, 3) +
33
- build_pow(tens, 2) +
34
- build_pow(ones, 1)
31
+ build_pow(thousands, 3) +
32
+ build_pow(hundreds, 2) +
33
+ build_pow(tens, 1) +
34
+ build_pow(ones, 0)
35
35
  end
36
36
 
37
37
  def build_pow(number, pow)
38
- literals = pow_literals(pow)
38
+ literals = CousinRoman.literals_for_pow pow
39
39
 
40
40
  case number
41
41
  when 1..3 then literals[:one]*number
@@ -45,23 +45,5 @@ module CousinRoman
45
45
  else ""
46
46
  end
47
47
  end
48
-
49
- def pow_literals(pow)
50
- one_literal, _ = ONES.find do |literal, value|
51
- value >= 10 ** (pow - 1) and value < 10 ** pow
52
- end
53
- five_literal, _ = FIVES.find do |literal, value|
54
- value >= 10 ** (pow - 1) and value < 10 ** pow
55
- end
56
- subtractive_literals = {}
57
- SUBTRACTIVES.select do |literal, value|
58
- value >= 10 ** (pow - 1) and value < 10 ** pow
59
- end.each do |literal, number|
60
- order = number / (10 ** (pow - 1))
61
- subtractive_literals[order] = literal
62
- end
63
-
64
- {one: one_literal, five: five_literal, subtractives: subtractive_literals}
65
- end
66
48
  end
67
49
  end
@@ -18,12 +18,11 @@ module CousinRoman
18
18
  # 2. Sum this numeric values to get the final answer
19
19
  def convert(number)
20
20
  intermediate = number.dup.downcase
21
- SUBTRACTIVES.each do |factor, value|
22
- intermediate.gsub!(factor, "(#{value})")
23
- end
24
- ONES.merge(FIVES).each do |factor, value|
25
- intermediate.gsub!(factor, "(#{value})")
26
- end
21
+ compound = braketize_value_of SUBTRACTIVES
22
+ singular = braketize_value_of ONES.merge(FIVES)
23
+
24
+ compound.each { |literal, val| intermediate.gsub!(literal, val) }
25
+ singular.each { |literal, val| intermediate.gsub!(literal, val) }
27
26
 
28
27
  intermediate.scan(/\((\d*)\)/).reduce(0) do |sum, term|
29
28
  sum + term.first.to_i
@@ -47,5 +46,12 @@ module CousinRoman
47
46
  def roman_regex
48
47
  /^(M{0,3})(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$/i
49
48
  end
49
+
50
+ private
51
+
52
+ # Make hash of the following structure {'i' => '(1)', 'v' => '(5)'...}
53
+ def braketize_value_of(factors)
54
+ Hash[factors.map { |literal, val| [literal, "(#{val})"] } ]
55
+ end
50
56
  end
51
57
  end
@@ -1,3 +1,3 @@
1
1
  module CousinRoman
2
- VERSION = "1.0.4"
2
+ VERSION = "1.0.5"
3
3
  end
data/lib/cousin_roman.rb CHANGED
@@ -38,4 +38,16 @@ module CousinRoman
38
38
  }
39
39
 
40
40
  FACTORS = ONES.merge(FIVES).merge(SUBTRACTIVES)
41
+
42
+ def self.literals_for_pow(pow)
43
+ one, five = ONES.keys[pow], FIVES.keys[pow]
44
+ subtractives = if pow.between? 0, 2
45
+ skeys = SUBTRACTIVES.keys
46
+ { 4 => skeys[pow*2], 9 => skeys[pow*2 + 1] }
47
+ else
48
+ nil
49
+ end
50
+
51
+ { one: one, five: five, subtractives: subtractives }
52
+ end
41
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cousin_roman
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Pyanykh