roman_converter 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +14 -0
- data/LICENSE +22 -0
- data/README.md +32 -0
- data/Rakefile +12 -0
- data/lib/roman_converter.rb +14 -0
- data/lib/roman_converter/roman.rb +26 -0
- data/lib/roman_converter/roman_util.rb +164 -0
- data/lib/roman_converter/rules.rb +27 -0
- data/lib/roman_converter/version.rb +3 -0
- data/roman_converter.gemspec +19 -0
- data/test/test_helper.rb +17 -0
- data/test/unit/roman_converter/roman_test.rb +59 -0
- data/test/unit/roman_converter/roman_util_test.rb +145 -0
- metadata +80 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Manjunath Manohar
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# RomanConverter
|
2
|
+
|
3
|
+
Roman Converter converts a roman numeral to an english / modern number.
|
4
|
+
|
5
|
+
The gem checks for the validity of the roman numeral string, before converting.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'roman_converter'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install roman_converter
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Please add tests for the feature which you have built
|
30
|
+
4. Commit your changes (`git commit -am 'Added some feature'`)
|
31
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
6. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path('../roman_converter/roman.rb', __FILE__)
|
2
|
+
require File.expand_path('../roman_converter/roman_util.rb', __FILE__)
|
3
|
+
require File.expand_path('../roman_converter/rules.rb', __FILE__)
|
4
|
+
|
5
|
+
module RomanConverter
|
6
|
+
|
7
|
+
String.class_eval do
|
8
|
+
def to_number
|
9
|
+
roman = RomanConverter::Roman.new(self)
|
10
|
+
roman.convert_to_number
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.expand_path('../rules.rb', __FILE__)
|
2
|
+
require File.expand_path('../roman_util.rb', __FILE__)
|
3
|
+
|
4
|
+
module RomanConverter
|
5
|
+
class Roman
|
6
|
+
attr_reader :input, :roman_array
|
7
|
+
attr_accessor :roman_util
|
8
|
+
|
9
|
+
def initialize(string)
|
10
|
+
@input = string
|
11
|
+
@roman_array = @input.split("")
|
12
|
+
@roman_util = RomanConverter::RomanUtil.new(@roman_array)
|
13
|
+
end
|
14
|
+
|
15
|
+
def is_valid?
|
16
|
+
!@roman_util.is_invalid?
|
17
|
+
end
|
18
|
+
|
19
|
+
# Converts the roman numerals into english mumber
|
20
|
+
# => english number / false if invalid roman numeral combination
|
21
|
+
def convert_to_number
|
22
|
+
@roman_util.compute_number
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require File.expand_path('../rules.rb', __FILE__)
|
2
|
+
|
3
|
+
module RomanConverter
|
4
|
+
class RomanUtil
|
5
|
+
attr_reader :roman_array
|
6
|
+
|
7
|
+
def initialize(roman_array)
|
8
|
+
@roman_array = roman_array
|
9
|
+
end
|
10
|
+
|
11
|
+
# Converts the roman numerals into english mumber
|
12
|
+
# => english number / false if invalid roman numeral combination
|
13
|
+
def compute_number
|
14
|
+
is_invalid? ? false : generate_number
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# This method can be called directly on the roman_utils object provided the **roman_array** is valid?
|
19
|
+
# Adds the values, if subtraction is required, then the iterator moves back and subtracts the value
|
20
|
+
# => english number
|
21
|
+
def generate_number
|
22
|
+
number = 0
|
23
|
+
@roman_array.each_with_index do |roman_number, array_index|
|
24
|
+
current_element_value = RomanConverter::Rules::Mapper::VALUES[roman_number]
|
25
|
+
number += current_element_value
|
26
|
+
if array_index > 0
|
27
|
+
previous_element_value = RomanConverter::Rules::Mapper::VALUES[@roman_array[array_index - 1]]
|
28
|
+
if previous_element_value < current_element_value
|
29
|
+
# Here 2 is multiplied as the **previous_element_value** was previously added to the **number**
|
30
|
+
number -= (previous_element_value * 2)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
number
|
35
|
+
end
|
36
|
+
|
37
|
+
def is_invalid?
|
38
|
+
is_invalid_numerals? ||
|
39
|
+
is_repeating_succession? ||
|
40
|
+
invalidate_never_repeatable_elements? ||
|
41
|
+
invalidate_repeatable_elements? ||
|
42
|
+
invalidate_subtractable_elements?
|
43
|
+
end
|
44
|
+
|
45
|
+
# Checks whether all the elements have proper roman numerals
|
46
|
+
# => true / false
|
47
|
+
def is_invalid_numerals?
|
48
|
+
(@roman_array & RomanConverter::Rules::Mapper::VALUES.keys).size != @roman_array.uniq.size
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns true if there is more than **MAX_SUCCESSIVE** successive elements
|
52
|
+
# => true/false
|
53
|
+
def is_repeating_succession?
|
54
|
+
!generate_occurrence_list.find{|chunk| chunk.last > RomanConverter::Rules::MAX_SUCCESSIVE}.nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns true if there are never repeatable elements occuring more than once
|
58
|
+
# => true/false
|
59
|
+
def invalidate_never_repeatable_elements?
|
60
|
+
chunk_hash = generate_occurrence_hash
|
61
|
+
RomanConverter::Rules::Mapper::NEVER_REPEATABLE.select{|element| !chunk_hash[element].nil? }.each do |roman_literal|
|
62
|
+
return true if chunk_hash[roman_literal] > 1
|
63
|
+
end
|
64
|
+
return false
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns true if there are repeatable elements occuring more than **MAX_OCCURENCE**
|
68
|
+
# Also, checks if there occurs repeatable elements occurring **MAX_OCCURENCE** times and respecting the condition
|
69
|
+
# that it needs to be interleaved.
|
70
|
+
# => true/false
|
71
|
+
def invalidate_repeatable_elements?
|
72
|
+
chunk_hash = generate_occurrence_hash
|
73
|
+
chunk_list = generate_occurrence_list
|
74
|
+
RomanConverter::Rules::Mapper::REPEATABLE.each do |roman_literal|
|
75
|
+
next if chunk_hash[roman_literal].nil?
|
76
|
+
if chunk_hash[roman_literal] > RomanConverter::Rules::MAX_OCCURENCE
|
77
|
+
return true
|
78
|
+
elsif chunk_hash[roman_literal] == Rules::MAX_OCCURENCE
|
79
|
+
chunk_list_index = chunk_list.find_index{|chunk_array| chunk_array.first == roman_literal}
|
80
|
+
next_index = chunk_list_index + 1
|
81
|
+
# Check for only one small character can occur between **MAX_OCCCURRENCE** times repeating character is made.
|
82
|
+
return true if chunk_list[next_index].nil? || (chunk_list[next_index].last > 1) || compare_mapper_values?(chunk_list[next_index].first, roman_literal, false)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
return false
|
86
|
+
end
|
87
|
+
|
88
|
+
# invalidates the subtraction rules
|
89
|
+
# This method assumes that the **NEVER_REPEATABLE** elements occur only once.
|
90
|
+
# Thus this method must be called after the **invalidate_never_repeatable_elements?**
|
91
|
+
# => true / false
|
92
|
+
def invalidate_subtractable_elements?
|
93
|
+
RomanConverter::Rules::Mapper::NEVER_REPEATABLE.each do |roman_literal|
|
94
|
+
next_element = get_next_elements(roman_literal).first
|
95
|
+
return true if !next_element.nil? && compare_mapper_values?(next_element, roman_literal, false)
|
96
|
+
end
|
97
|
+
RomanConverter::Rules::Mapper::SUBTRACTABLE_ELEMENTS.each do |roman_literal|
|
98
|
+
next_elements = get_next_elements(roman_literal)
|
99
|
+
next_elements.each do |next_element|
|
100
|
+
return true if !next_element.nil? && can_subtract?(roman_literal, next_element) && !RomanConverter::Rules::Mapper::SUBTRACTABLE_ELIGIBLE[roman_literal].include?(next_element)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
return false
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def can_subtract?(key1, key2)
|
109
|
+
compare_mapper_values?(key1, key2)
|
110
|
+
end
|
111
|
+
|
112
|
+
def compare_mapper_values?(key1, key2, lesser = true)
|
113
|
+
lesser ? mapper_value_less_than?(key1, key2) : mapper_value_greater_than?(key1, key2)
|
114
|
+
end
|
115
|
+
|
116
|
+
def mapper_value_greater_than?(key1, key2)
|
117
|
+
RomanConverter::Rules::Mapper::VALUES[key1] > RomanConverter::Rules::Mapper::VALUES[key2]
|
118
|
+
end
|
119
|
+
|
120
|
+
def mapper_value_less_than?(key1, key2)
|
121
|
+
RomanConverter::Rules::Mapper::VALUES[key1] < RomanConverter::Rules::Mapper::VALUES[key2]
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns the next elements of the matched elements with **roman_literal** in the array
|
125
|
+
# => **@roman_array** = [1, 2, 3, 4, 5, 7, 1]
|
126
|
+
# => get_next_elements(1)
|
127
|
+
# => [2, nil]
|
128
|
+
# => get_next_elements(2)
|
129
|
+
# => [3]
|
130
|
+
def get_next_elements(roman_literal)
|
131
|
+
index_map = @roman_array.map.with_index.to_a
|
132
|
+
selected_array = index_map.select { |index_array| index_array.first == roman_literal }
|
133
|
+
selected_array.collect{ |index_array| @roman_array[index_array.last + 1]}
|
134
|
+
end
|
135
|
+
|
136
|
+
# => generate_occurrence_hash([1,2,3,4,6,6,6,1,6])
|
137
|
+
# => {1=>2, 2=>1, 3=>1, 4=>1, 6=>4}
|
138
|
+
def generate_occurrence_hash
|
139
|
+
occurrence_hash = {}
|
140
|
+
generate_chunks do |category, chunk_array|
|
141
|
+
num = occurrence_hash[category]
|
142
|
+
occurrence_hash[category] = num.to_i + chunk_array.size
|
143
|
+
end
|
144
|
+
occurrence_hash
|
145
|
+
end
|
146
|
+
|
147
|
+
# => generate_occurrence_list([1,2,3,4,6,6,6,1,6])
|
148
|
+
# => [[1, 1], [2, 1], [3, 1], [4, 1], [6, 3], [1, 1], [6, 1]]
|
149
|
+
def generate_occurrence_list
|
150
|
+
generate_chunks do |category, chunk_array|
|
151
|
+
[category, chunk_array.size]
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# The method below categorises the successive elements and groups and returns based on the block
|
156
|
+
# => generate_chunks([1,2,3,4,6,6,6]){|a, b| [a, b.size]}
|
157
|
+
# => [[1, 1], [2, 1], [3, 1], [4, 1], [6, 3]]
|
158
|
+
def generate_chunks(&block)
|
159
|
+
@roman_array.chunk{|y| y}.map do |category, chunk_array|
|
160
|
+
block.call(category, chunk_array)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RomanConverter
|
2
|
+
module Rules
|
3
|
+
MAX_SUCCESSIVE = 3
|
4
|
+
MAX_OCCURENCE = 4
|
5
|
+
module Mapper
|
6
|
+
VALUES = {
|
7
|
+
"I" => 1,
|
8
|
+
"V" => 5,
|
9
|
+
"X" => 10,
|
10
|
+
"L" => 50,
|
11
|
+
"C" => 100,
|
12
|
+
"D" => 500,
|
13
|
+
"M" => 1000
|
14
|
+
}
|
15
|
+
|
16
|
+
REPEATABLE = ["I", "X", "C", "M"]
|
17
|
+
NEVER_REPEATABLE = ["D", "L", "V"]
|
18
|
+
|
19
|
+
SUBTRACTABLE_ELEMENTS = ["I", "X", "C"]
|
20
|
+
SUBTRACTABLE_ELIGIBLE = {
|
21
|
+
"I" => ["V", "X"],
|
22
|
+
"X" => ["L", "C"],
|
23
|
+
"C" => ["D", "M"]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/roman_converter/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Manjunath Manohar"]
|
6
|
+
gem.email = ["manjunath.nm89@gmail.com"]
|
7
|
+
gem.description = "Roman Converter converts a roman numeral to an english / modern number. Making sure all rules invloved in the formation of a roman numeral is obeyed."
|
8
|
+
gem.summary = "Roman Converter converts a roman numeral to an english / modern number"
|
9
|
+
gem.homepage = "http://technical-arsenal.blogspot.in"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "roman_converter"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = RomanConverter::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency 'debugger'
|
19
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
def assert_false(boolean)
|
4
|
+
assert !boolean
|
5
|
+
end
|
6
|
+
|
7
|
+
def create_roman_util(string)
|
8
|
+
RomanConverter::RomanUtil.new(create_roman_array(string))
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_roman(string)
|
12
|
+
RomanConverter::Roman.new(string)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_roman_array(input_string)
|
16
|
+
input_string.split("")
|
17
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path('../../../../lib/roman_converter/roman.rb', __FILE__)
|
3
|
+
require File.expand_path('../../../../test/test_helper.rb', __FILE__)
|
4
|
+
|
5
|
+
class RomanConverter::RomanTest < Test::Unit::TestCase
|
6
|
+
def test_is_valid?
|
7
|
+
roman = create_roman("XVI")
|
8
|
+
assert_equal "XVI", roman.input
|
9
|
+
assert_equal ["X", "V", "I"], roman.roman_array
|
10
|
+
assert roman.is_valid?
|
11
|
+
assert_equal 16, roman.convert_to_number
|
12
|
+
|
13
|
+
roman = create_roman("XXVI")
|
14
|
+
assert roman.is_valid?
|
15
|
+
assert_equal 26, roman.convert_to_number
|
16
|
+
|
17
|
+
roman = create_roman("VV")
|
18
|
+
assert_false roman.is_valid?
|
19
|
+
assert_false roman.convert_to_number
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_convert_to_number
|
23
|
+
roman = create_roman("D")
|
24
|
+
assert_equal 500, roman.convert_to_number
|
25
|
+
|
26
|
+
roman = create_roman("M")
|
27
|
+
assert_equal 1000, roman.convert_to_number
|
28
|
+
|
29
|
+
roman = create_roman("V")
|
30
|
+
assert_equal 5, roman.convert_to_number
|
31
|
+
|
32
|
+
roman = create_roman("IV")
|
33
|
+
assert_equal 4, roman.convert_to_number
|
34
|
+
|
35
|
+
roman = create_roman("XXXIX")
|
36
|
+
assert_equal 39, roman.convert_to_number
|
37
|
+
|
38
|
+
roman = create_roman("MCMXC")
|
39
|
+
assert_equal 1990, roman.convert_to_number
|
40
|
+
|
41
|
+
roman = create_roman("CV")
|
42
|
+
assert_equal 105, roman.convert_to_number
|
43
|
+
|
44
|
+
roman = create_roman("XV")
|
45
|
+
assert_equal 15, roman.convert_to_number
|
46
|
+
|
47
|
+
roman = create_roman("MMXIII")
|
48
|
+
assert_equal 2013, roman.convert_to_number
|
49
|
+
|
50
|
+
roman = create_roman("XVI")
|
51
|
+
assert_equal 16, roman.convert_to_number
|
52
|
+
|
53
|
+
roman = create_roman("MMXIIII")
|
54
|
+
assert_false roman.convert_to_number
|
55
|
+
|
56
|
+
roman = create_roman("VC")
|
57
|
+
assert_false roman.convert_to_number
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path('../../../../lib/roman_converter/roman_util.rb', __FILE__)
|
3
|
+
require File.expand_path('../../../../test/test_helper.rb', __FILE__)
|
4
|
+
|
5
|
+
class RomanConverter::RomanUtilTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_is_invalid_numerals
|
8
|
+
roman_util = create_roman_util("MXVIMANJU")
|
9
|
+
assert roman_util.is_invalid?
|
10
|
+
assert roman_util.is_invalid_numerals?
|
11
|
+
|
12
|
+
roman_util = create_roman_util("MXVI")
|
13
|
+
assert_false roman_util.is_invalid_numerals?
|
14
|
+
|
15
|
+
roman_util = create_roman_util("X")
|
16
|
+
assert_false roman_util.is_invalid_numerals?
|
17
|
+
|
18
|
+
roman_util = create_roman_util("AM")
|
19
|
+
assert roman_util.is_invalid_numerals?
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_is_repeating_succession
|
23
|
+
roman_util = create_roman_util("MXVI")
|
24
|
+
assert_false roman_util.is_repeating_succession?
|
25
|
+
|
26
|
+
roman_util = create_roman_util("MMMCM")
|
27
|
+
assert_false roman_util.is_repeating_succession?
|
28
|
+
|
29
|
+
roman_util = create_roman_util("MMMMM")
|
30
|
+
assert roman_util.is_repeating_succession?
|
31
|
+
assert roman_util.is_invalid?
|
32
|
+
|
33
|
+
roman_util = create_roman_util("MMMMCCCCC")
|
34
|
+
assert roman_util.is_repeating_succession?
|
35
|
+
assert roman_util.is_invalid?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_invalidate_never_repeatable_elements
|
39
|
+
roman_util = create_roman_util("CD")
|
40
|
+
assert_false roman_util.invalidate_never_repeatable_elements?
|
41
|
+
|
42
|
+
roman_util = create_roman_util("DDD")
|
43
|
+
assert roman_util.invalidate_never_repeatable_elements?
|
44
|
+
assert roman_util.is_invalid?
|
45
|
+
|
46
|
+
roman_util = create_roman_util("XLLL")
|
47
|
+
assert roman_util.invalidate_never_repeatable_elements?
|
48
|
+
assert roman_util.is_invalid?
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_invalidate_repeatable_elements_for_greater_than_max_occurrence
|
52
|
+
roman_util = create_roman_util("CCCD")
|
53
|
+
assert_false roman_util.invalidate_repeatable_elements?
|
54
|
+
|
55
|
+
roman_util = create_roman_util("XXXIX")
|
56
|
+
assert_false roman_util.invalidate_repeatable_elements?
|
57
|
+
|
58
|
+
roman_util = create_roman_util("CCCDCC")
|
59
|
+
assert roman_util.invalidate_repeatable_elements?
|
60
|
+
|
61
|
+
roman_util = create_roman_util("III")
|
62
|
+
assert_false roman_util.invalidate_repeatable_elements?
|
63
|
+
|
64
|
+
roman_util = create_roman_util("IIII")
|
65
|
+
assert roman_util.invalidate_repeatable_elements?
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_invalidate_repeatable_elements_for_separated_by_a_single_small_value
|
69
|
+
roman_util = create_roman_util("XXXIX")
|
70
|
+
assert_false roman_util.invalidate_repeatable_elements?
|
71
|
+
|
72
|
+
roman_util = create_roman_util("XXXIIX")
|
73
|
+
assert roman_util.invalidate_repeatable_elements?
|
74
|
+
|
75
|
+
roman_util = create_roman_util("XXXCX")
|
76
|
+
assert roman_util.invalidate_repeatable_elements?
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_invalidate_subtractable_elements_for_never_repeatable
|
80
|
+
roman_util = create_roman_util("D")
|
81
|
+
assert_false roman_util.invalidate_subtractable_elements?
|
82
|
+
|
83
|
+
roman_util = create_roman_util("DI")
|
84
|
+
assert_false roman_util.invalidate_subtractable_elements?
|
85
|
+
|
86
|
+
roman_util = create_roman_util("ID")
|
87
|
+
assert roman_util.invalidate_subtractable_elements?
|
88
|
+
|
89
|
+
roman_util = create_roman_util("IV")
|
90
|
+
assert_false roman_util.invalidate_subtractable_elements?
|
91
|
+
|
92
|
+
roman_util = create_roman_util("IX")
|
93
|
+
assert_false roman_util.invalidate_subtractable_elements?
|
94
|
+
|
95
|
+
roman_util = create_roman_util("XL")
|
96
|
+
assert_false roman_util.invalidate_subtractable_elements?
|
97
|
+
|
98
|
+
roman_util = create_roman_util("XV")
|
99
|
+
assert_false roman_util.invalidate_subtractable_elements?
|
100
|
+
|
101
|
+
roman_util = create_roman_util("CD")
|
102
|
+
assert_false roman_util.invalidate_subtractable_elements?
|
103
|
+
|
104
|
+
roman_util = create_roman_util("VC")
|
105
|
+
assert roman_util.invalidate_subtractable_elements?
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_compute_number
|
109
|
+
roman_util = create_roman_util("D")
|
110
|
+
assert_equal 500, roman_util.compute_number
|
111
|
+
|
112
|
+
roman_util = create_roman_util("M")
|
113
|
+
assert_equal 1000, roman_util.compute_number
|
114
|
+
|
115
|
+
roman_util = create_roman_util("V")
|
116
|
+
assert_equal 5, roman_util.compute_number
|
117
|
+
|
118
|
+
roman_util = create_roman_util("IV")
|
119
|
+
assert_equal 4, roman_util.compute_number
|
120
|
+
|
121
|
+
roman_util = create_roman_util("XXXIX")
|
122
|
+
assert_equal 39, roman_util.compute_number
|
123
|
+
|
124
|
+
roman_util = create_roman_util("MCMXC")
|
125
|
+
assert_equal 1990, roman_util.compute_number
|
126
|
+
|
127
|
+
roman_util = create_roman_util("CV")
|
128
|
+
assert_equal 105, roman_util.compute_number
|
129
|
+
|
130
|
+
roman_util = create_roman_util("XV")
|
131
|
+
assert_equal 15, roman_util.compute_number
|
132
|
+
|
133
|
+
roman_util = create_roman_util("MMXIII")
|
134
|
+
assert_equal 2013, roman_util.compute_number
|
135
|
+
|
136
|
+
roman_util = create_roman_util("XVI")
|
137
|
+
assert_equal 16, roman_util.compute_number
|
138
|
+
|
139
|
+
roman_util = create_roman_util("MMXIIII")
|
140
|
+
assert_false roman_util.compute_number
|
141
|
+
|
142
|
+
roman_util = create_roman_util("VC")
|
143
|
+
assert_false roman_util.compute_number
|
144
|
+
end
|
145
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: roman_converter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Manjunath Manohar
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: debugger
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Roman Converter converts a roman numeral to an english / modern number.
|
31
|
+
Making sure all rules invloved in the formation of a roman numeral is obeyed.
|
32
|
+
email:
|
33
|
+
- manjunath.nm89@gmail.com
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- Gemfile
|
40
|
+
- Gemfile.lock
|
41
|
+
- LICENSE
|
42
|
+
- README.md
|
43
|
+
- Rakefile
|
44
|
+
- lib/roman_converter.rb
|
45
|
+
- lib/roman_converter/roman.rb
|
46
|
+
- lib/roman_converter/roman_util.rb
|
47
|
+
- lib/roman_converter/rules.rb
|
48
|
+
- lib/roman_converter/version.rb
|
49
|
+
- roman_converter.gemspec
|
50
|
+
- test/test_helper.rb
|
51
|
+
- test/unit/roman_converter/roman_test.rb
|
52
|
+
- test/unit/roman_converter/roman_util_test.rb
|
53
|
+
homepage: http://technical-arsenal.blogspot.in
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.8.24
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Roman Converter converts a roman numeral to an english / modern number
|
77
|
+
test_files:
|
78
|
+
- test/test_helper.rb
|
79
|
+
- test/unit/roman_converter/roman_test.rb
|
80
|
+
- test/unit/roman_converter/roman_util_test.rb
|