cousin_roman 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
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