roman_numbers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6daa393f9570d95a67b67cd1a84a135998311b4b
4
+ data.tar.gz: 60cc1370d2fc105f826ad919e2338c20078db105
5
+ SHA512:
6
+ metadata.gz: 3033cdc3ec59fd57255b2c13534c5f418c36a7874d0cb53e81e7f19f098aa4887af93cdba16ab19c0773ea71c4b7618c49168c5a204fc29e747889e6d9a9db97
7
+ data.tar.gz: 222fc3d1e1555efc9f1384db184c8097885204d510971d19993f6a7453a2a2db25502c457e8542289d77f6b5d3dea47f70d76ad73aef776193a7a642ce7790e7
data/.gitignore ADDED
@@ -0,0 +1,26 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ # Ignore RubyMine's .idea directory
20
+ /.idea/*
21
+
22
+ # Ignore Aptana's .project file
23
+ /.project
24
+
25
+ # Ignoring .rvmrc
26
+ /.rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in roman_numbers.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 G580 mgoyal
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,51 @@
1
+ # RomanNumbers
2
+
3
+ Conversion between Integers and Roman Numbers
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'roman_numbers'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install roman_numbers
18
+
19
+ ## Usage
20
+
21
+ Some Examples:
22
+
23
+ > RomanNumbers::RomanNumber.new(3999).convert_decimal_to_roman
24
+ "MMMCMXCIX"
25
+
26
+ > RomanNumbers::RomanNumber.new('MMMCMXCIX').convert_roman_to_decimal
27
+ 3999
28
+
29
+ > 'MCMXLIV'.from_roman_to_integer
30
+ 1944
31
+
32
+ > 1944.to_roman
33
+ "MCMXLIV"
34
+
35
+ > 'MMMMMX'.from_roman_to_integer
36
+ RomanNumbers::InvalidInputError
37
+
38
+ > 999383.to_roman
39
+ RomanNumbers::InvalidInputError
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it
44
+
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+
47
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
48
+
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+
51
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ Autotest.add_discovery { "rspec2" }
2
+
@@ -0,0 +1,29 @@
1
+ require 'roman_numbers/version'
2
+ require 'roman_numbers/roman_number'
3
+
4
+ module RomanNumbers
5
+ # custom Exceptions
6
+ class Error < StandardError;
7
+ end
8
+ class StartsWithNonRepeatableRomanUnitError < Error;
9
+ end
10
+ class NonReachableCodeError < Error;
11
+ end
12
+ class InvalidInputError < Error;
13
+ end
14
+ end
15
+
16
+ # opening String class to add from_roman_to_integer method
17
+ class String
18
+ def from_roman_to_integer
19
+ RomanNumbers::RomanNumber.new(self).convert_roman_to_decimal
20
+ end
21
+ end
22
+
23
+ # opening Integer class to add from_integer_to_roman method
24
+ class Integer
25
+ def to_roman
26
+ RomanNumbers::RomanNumber.new(self).convert_decimal_to_roman
27
+ end
28
+ end
29
+
@@ -0,0 +1,166 @@
1
+ require 'roman_numbers/version'
2
+
3
+ module RomanNumbers
4
+ class RomanNumber
5
+
6
+ ROMAN_REPEATABLE_UNITS = [
7
+ {:unit => :M, :value => 1000}, # element first
8
+ {:unit => :C, :value => 100},
9
+ {:unit => :X, :value => 10},
10
+ {:unit => :I, :value => 1} # element last
11
+ ].sort { |x, y| y[:value] <=> x[:value] }
12
+
13
+ ROMAN_NON_REPEATABLE_UNITS_1 = [
14
+ {:unit => :D, :value => 500}, # element first
15
+ {:unit => :L, :value => 50},
16
+ {:unit => :V, :value => 5}, # element last
17
+ ].sort { |x, y| y[:value] <=> x[:value] }
18
+
19
+ ROMAN_NON_REPEATABLE_UNITS_2 = [
20
+ {:unit => :CM, :value => 900}, # element first
21
+ {:unit => :CD, :value => 400},
22
+ {:unit => :XC, :value => 90},
23
+ {:unit => :XL, :value => 40},
24
+ {:unit => :IX, :value => 9},
25
+ {:unit => :IV, :value => 4} # element last
26
+ ].sort { |x, y| y[:value] <=> x[:value] }
27
+
28
+ ROMAN_NON_REPEATABLE_UNITS = (ROMAN_NON_REPEATABLE_UNITS_1 + ROMAN_NON_REPEATABLE_UNITS_2).sort { |x, y| y[:value] <=> x[:value] }
29
+ ROMAN_DOUBLE_UNITS = ROMAN_NON_REPEATABLE_UNITS_2.sort { |x, y| y[:value] <=> x[:value] }
30
+ ROMAN_SINGLE_UNITS = (ROMAN_NON_REPEATABLE_UNITS_1 + ROMAN_REPEATABLE_UNITS).sort { |x, y| y[:value] <=> x[:value] }
31
+ ROMAN_UNITS = (ROMAN_REPEATABLE_UNITS + ROMAN_NON_REPEATABLE_UNITS_1 + ROMAN_NON_REPEATABLE_UNITS_2).sort { |x, y| y[:value] <=> x[:value] }
32
+
33
+ # based on above non_repeatable units, allowed repetition is 3
34
+ MAX_ALLOWED_REPETITION = 3
35
+
36
+ # initializing element
37
+ def initialize(input)
38
+ # checking input type and setting instance variables
39
+ case input
40
+ when Integer
41
+ @input_integer = input
42
+ @staged_roman_hash = Array.new
43
+ @output_roman = String.new
44
+ when String
45
+ @input_string = input.upcase
46
+ @output_arabic = 0
47
+ end
48
+ end
49
+
50
+ # converts arabic to roman
51
+ def convert_decimal_to_roman(input_integer=@input_integer)
52
+ # validating input
53
+ unless (1..3999).include? input_integer
54
+ raise InvalidInputError, "Invalid Input: #{input_integer}"
55
+ end
56
+ # getting staged roman hash
57
+ calculate_staged_roman_hash(input_integer)
58
+ # extracting hash from staged roman hash
59
+ @staged_roman_hash.each do |element|
60
+ @output_roman << (element[:largest_element][:unit].to_s)*(element[:times])
61
+ end
62
+ return @output_roman
63
+ end
64
+
65
+ # converts given arabic number (in string form) to corresponding integer
66
+ def convert_roman_to_decimal(input_roman=@input_string.clone)
67
+ input_roman
68
+ # generating regex expressions
69
+ double_units_array = ROMAN_NON_REPEATABLE_UNITS_2.map { |element| ('^' + element[:unit].to_s) }
70
+ single_units_array = (ROMAN_REPEATABLE_UNITS + ROMAN_NON_REPEATABLE_UNITS_1).map { |element| ('^' + element[:unit].to_s) }
71
+ double_units_regex = Regexp.new(double_units_array.join('|'))
72
+ single_units_regex = Regexp.new(single_units_array.join('|'))
73
+ # validation
74
+ # TODO: to add more validations
75
+ if input_roman =~ /(.)\1{#{MAX_ALLOWED_REPETITION},}/
76
+ raise InvalidInputError, "Invalid Input: #{input_roman}"
77
+ end
78
+ # processing
79
+ if input_roman.length > 0
80
+ if unit = input_roman.slice!(double_units_regex)
81
+ @output_arabic += ROMAN_DOUBLE_UNITS.find { |element| element[:unit] == unit.to_sym }[:value]
82
+ convert_roman_to_decimal(input_roman)
83
+ elsif unit = input_roman.slice!(single_units_regex)
84
+ @output_arabic += ROMAN_SINGLE_UNITS.find { |element| element[:unit] == unit.to_sym }[:value]
85
+ convert_roman_to_decimal(input_roman)
86
+ else
87
+ # invalud input
88
+ raise InvalidInputError, "Invalid Input: #{input_roman}"
89
+ end
90
+ else
91
+ # process is complete
92
+ return @output_arabic
93
+ end
94
+
95
+ end
96
+
97
+ # returns an array of hashed containing info on desired output roman
98
+ def calculate_staged_roman_hash(input_integer)
99
+ begin
100
+ temp_hash = largest_repeatable_element(input_integer)
101
+ rescue StartsWithNonRepeatableRomanUnitError => ex
102
+ temp_hash = largest_non_repeatable_element(input_integer)
103
+ end
104
+ if temp_hash
105
+ @staged_roman_hash << temp_hash
106
+ input_integer = temp_hash[:reduced_integer]
107
+ calculate_staged_roman_hash(input_integer)
108
+ else
109
+ # processing done
110
+ return @staged_roman_hash
111
+ end
112
+ end
113
+
114
+ # returns reduced_integer, largest repeatable element, and number of times it can be repeated
115
+ def largest_repeatable_element(input_integer)
116
+ if input_integer > 0
117
+ largest_element = ROMAN_REPEATABLE_UNITS.find { |element| input_integer >= element[:value] }
118
+ # TODO: make it efficient by removing elements before largest_element
119
+ # TODO: to use binary search instead
120
+ if largest_element
121
+ times = input_integer/largest_element[:value]
122
+ reduced_integer = input_integer%largest_element[:value]
123
+ if times > MAX_ALLOWED_REPETITION
124
+ # given integer starts with non_repeatable roman unit
125
+ raise StartsWithNonRepeatableRomanUnitError
126
+ end
127
+ return {:reduced_integer => reduced_integer, :largest_element => largest_element, :times => times}
128
+ else
129
+ # non-reachable code
130
+ raise NonReachableCodeError, 'LargestElementIsNil'
131
+ end
132
+ elsif input_integer == 0
133
+ # process completed
134
+ return nil
135
+ else
136
+ # non-reachable code
137
+ # input_integer has to be >=0
138
+ raise NonReachableCodeError, 'ReceivedNegativeInteger'
139
+ end
140
+ end
141
+
142
+ # returns largest non-repeatable element
143
+ def largest_non_repeatable_element(input_integer)
144
+ if input_integer > 0
145
+ largest_element = ROMAN_NON_REPEATABLE_UNITS.find { |element| input_integer >= element[:value] }
146
+ # TODO: make it efficient by removing elements before largest_element
147
+ # TODO: to use binary search instead
148
+ if largest_element
149
+ reduced_integer = input_integer%largest_element[:value]
150
+ return {:reduced_integer => reduced_integer, :largest_element => largest_element, :times => 1}
151
+ else
152
+ # no non_repeatable element preset, but process is not complete yet
153
+ return {:reduced_integer => input_integer, :largest_element => nil, :times => 0}
154
+ end
155
+ elsif input_integer == 0
156
+ # process completed
157
+ return nil
158
+ else
159
+ # non-reachable code
160
+ # input_integer has to be >=0
161
+ raise NonReachableCodeError, 'ReceivedNegativeInteger'
162
+ end
163
+ end
164
+
165
+ end
166
+ end
@@ -0,0 +1,3 @@
1
+ module RomanNumbers
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'roman_numbers/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "roman_numbers"
8
+ spec.version = RomanNumbers::VERSION
9
+ spec.authors = ["Munish Goyal"]
10
+ spec.email = ["munishapc@gmail.com"]
11
+ spec.description = %q{Conversion between Integers and Roman Numbers}
12
+ spec.summary = %q{Conversion between Integers and Roman Numbers}
13
+ spec.homepage = "https://github.com/goyalmunish/roman_numbers"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", ">= 1.3"
22
+ spec.add_development_dependency "rake", ">= 0.9"
23
+ spec.add_development_dependency "awesome_print", ">= 1.2"
24
+ spec.add_development_dependency "rspec", "~> 2.14"
25
+ spec.add_development_dependency "autotest"
26
+ spec.add_development_dependency "simplecov"
27
+ end
@@ -0,0 +1,252 @@
1
+ require_relative '../spec_helper'
2
+
3
+ module RomanNumbers
4
+ describe RomanNumber do # EXAMPLE GROUP
5
+ before(:each) do
6
+ @roman_number = RomanNumber.new(1)
7
+ end
8
+ describe '#largest_repeatable_element' do
9
+ it 'works for "3999" as input' do
10
+ output = @roman_number.largest_repeatable_element(3999)
11
+ output.should == {:reduced_integer => 999, :largest_element => {:unit => :M, :value => 1000}, :times => 3}
12
+ end
13
+ it 'works for "1066" as input' do
14
+ output = @roman_number.largest_repeatable_element(1066)
15
+ output.should == {:reduced_integer => 66, :largest_element => {:unit => :M, :value => 1000}, :times => 1}
16
+ end
17
+ it 'works for "207" as input' do
18
+ output = @roman_number.largest_repeatable_element(207)
19
+ output.should == {:reduced_integer => 7, :largest_element => {:unit => :C, :value => 100}, :times => 2}
20
+ end
21
+ it 'works for "10" as input' do
22
+ output = @roman_number.largest_repeatable_element(10)
23
+ output.should == {:reduced_integer => 0, :largest_element => {:unit => :X, :value => 10}, :times => 1}
24
+ end
25
+ it 'raises StartsWithNonRepeatableRomanUnitError for 999 as input' do
26
+ expect {
27
+ @roman_number.largest_repeatable_element(999)
28
+ }.to raise_error(StartsWithNonRepeatableRomanUnitError)
29
+ end
30
+ it 'raises StartsWithNonRepeatableRomanUnitError for 44 as input' do
31
+ expect {
32
+ @roman_number.largest_repeatable_element(44)
33
+ }.to raise_error(StartsWithNonRepeatableRomanUnitError)
34
+ end
35
+ end
36
+
37
+ describe '#largest_non_repeatable_element' do
38
+ before(:each) do
39
+ @roman_number = RomanNumber.new(1)
40
+ end
41
+ it 'works for "999" as input' do
42
+ output = @roman_number.largest_non_repeatable_element(999)
43
+ output.should == {:reduced_integer => 99, :largest_element => {:unit => :CM, :value => 900}, :times => 1}
44
+ end
45
+ it 'works for "900" as input' do
46
+ output = @roman_number.largest_non_repeatable_element(900)
47
+ output.should == {:reduced_integer => 0, :largest_element => {:unit => :CM, :value => 900}, :times => 1}
48
+ end
49
+ it 'works for "44" as input' do
50
+ output = @roman_number.largest_non_repeatable_element(44)
51
+ output.should == {:reduced_integer => 4, :largest_element => {:unit => :XL, :value => 40}, :times => 1}
52
+ end
53
+ it 'works for "49" as input' do
54
+ output = @roman_number.largest_non_repeatable_element(49)
55
+ output.should == {:reduced_integer => 9, :largest_element => {:unit => :XL, :value => 40}, :times => 1}
56
+ end
57
+ end
58
+
59
+ describe '#convert_arabic_to_roman' do
60
+ context 'For Very Simple Integers' do
61
+ it 'returns I for 1' do
62
+ RomanNumber.new(1).convert_decimal_to_roman.should == 'I'
63
+ end
64
+ it 'returns V for 5' do
65
+ RomanNumber.new(5).convert_decimal_to_roman.should == 'V'
66
+ end
67
+ it 'returns X for 10' do
68
+ RomanNumber.new(10).convert_decimal_to_roman.should == 'X'
69
+ end
70
+ it 'returns L for 50' do
71
+ RomanNumber.new(50).convert_decimal_to_roman.should == 'L'
72
+ end
73
+ it 'returns C for 100' do
74
+ RomanNumber.new(100).convert_decimal_to_roman.should == 'C'
75
+ end
76
+ it 'returns D for 500' do
77
+ RomanNumber.new(500).convert_decimal_to_roman.should == 'D'
78
+ end
79
+ it 'returns M for 1000' do
80
+ RomanNumber.new(1000).convert_decimal_to_roman.should == 'M'
81
+ end
82
+ end
83
+ context 'For Simple Integers' do
84
+ it 'returns IV for 4' do
85
+ RomanNumber.new(4).convert_decimal_to_roman.should == 'IV'
86
+ end
87
+ it 'returns IX for 9' do
88
+ RomanNumber.new(9).convert_decimal_to_roman.should == 'IX'
89
+ end
90
+ it 'returns XL for 40' do
91
+ RomanNumber.new(40).convert_decimal_to_roman.should == 'XL'
92
+ end
93
+ it 'returns XC for 90' do
94
+ RomanNumber.new(90).convert_decimal_to_roman.should == 'XC'
95
+ end
96
+ it 'returns CD for 400' do
97
+ RomanNumber.new(400).convert_decimal_to_roman.should == 'CD'
98
+ end
99
+ it 'returns CM for 900' do
100
+ RomanNumber.new(900).convert_decimal_to_roman.should == 'CM'
101
+ end
102
+ it 'returns CCVII for 207' do
103
+ RomanNumber.new(207).convert_decimal_to_roman.should == 'CCVII'
104
+ end
105
+ it 'returns MLXVI for 1066' do
106
+ RomanNumber.new(1066).convert_decimal_to_roman.should == 'MLXVI'
107
+ end
108
+ end
109
+ context 'For Complex Integers' do
110
+ it 'returns XLIV for 44' do
111
+ RomanNumber.new(44).convert_decimal_to_roman.should == 'XLIV'
112
+ end
113
+ it 'returns XLIX for 49' do
114
+ RomanNumber.new(49).convert_decimal_to_roman.should == 'XLIX'
115
+ end
116
+ it 'returns CMIV for 904' do
117
+ RomanNumber.new(904).convert_decimal_to_roman.should == 'CMIV'
118
+ end
119
+ it 'returns CMXLIV for 944' do
120
+ RomanNumber.new(944).convert_decimal_to_roman.should == 'CMXLIV'
121
+ end
122
+ it 'returns MCMIV for 1904' do
123
+ RomanNumber.new(1904).convert_decimal_to_roman.should == 'MCMIV'
124
+ end
125
+ it 'returns MCMXLIV for 1944' do
126
+ RomanNumber.new(1944).convert_decimal_to_roman.should == 'MCMXLIV'
127
+ end
128
+ end
129
+ context 'For Very Simple Integers' do
130
+ it 'returns MMMCMXCIX for 3999' do
131
+ RomanNumber.new(3999).convert_decimal_to_roman.should == 'MMMCMXCIX'
132
+ end
133
+ end
134
+ context 'For Invalid Input' do
135
+ it 'raises InvalidInputError for 4000 as input' do
136
+ expect {
137
+ RomanNumber.new(4000).convert_decimal_to_roman
138
+ }.to raise_error(InvalidInputError)
139
+ end
140
+ it 'raises InvalidInputError for 0 as input' do
141
+ expect {
142
+ RomanNumber.new(0).convert_decimal_to_roman
143
+ }.to raise_error(InvalidInputError)
144
+ end
145
+ it 'raises InvalidInputError for -10 as input' do
146
+ expect {
147
+ RomanNumber.new(-10).convert_decimal_to_roman
148
+ }.to raise_error(InvalidInputError)
149
+ end
150
+ it 'raises InvalidInputError for "10" as input' do
151
+ expect {
152
+ RomanNumber.new('10').convert_decimal_to_roman
153
+ }.to raise_error(InvalidInputError)
154
+ end
155
+ end
156
+ end
157
+
158
+ describe '#convert_roman_to_arabic' do
159
+ context 'For Simple Romans' do
160
+ it 'returns 1 for I' do
161
+ RomanNumber.new('I').convert_roman_to_decimal.should == 1
162
+ end
163
+ it 'returns 5 for V' do
164
+ RomanNumber.new('V').convert_roman_to_decimal.should == 5
165
+ end
166
+ it 'returns 10 for X' do
167
+ RomanNumber.new('X').convert_roman_to_decimal.should == 10
168
+ end
169
+ it 'returns 50 for L' do
170
+ RomanNumber.new('L').convert_roman_to_decimal.should == 50
171
+ end
172
+ it 'returns 100 for C' do
173
+ RomanNumber.new('C').convert_roman_to_decimal.should == 100
174
+ end
175
+ it 'returns 500 for D' do
176
+ RomanNumber.new('D').convert_roman_to_decimal.should == 500
177
+ end
178
+ it 'returns 1000 for M' do
179
+ RomanNumber.new('M').convert_roman_to_decimal.should == 1000
180
+ end
181
+ it 'returns 4 for IV' do
182
+ RomanNumber.new('IV').convert_roman_to_decimal.should == 4
183
+ end
184
+ it 'returns 9 for IX' do
185
+ RomanNumber.new('IX').convert_roman_to_decimal.should == 9
186
+ end
187
+ it 'returns 40 for XL' do
188
+ RomanNumber.new('XL').convert_roman_to_decimal.should == 40
189
+ end
190
+ it 'returns 90 for XC' do
191
+ RomanNumber.new('XC').convert_roman_to_decimal.should == 90
192
+ end
193
+ it 'returns 400 for CD' do
194
+ RomanNumber.new('CD').convert_roman_to_decimal.should == 400
195
+ end
196
+ it 'returns 900 for CM' do
197
+ RomanNumber.new('CM').convert_roman_to_decimal.should == 900
198
+ end
199
+ end
200
+ context 'For Complex Romans' do
201
+ it 'returns 207 for CCVII' do
202
+ RomanNumber.new('CCVII').convert_roman_to_decimal.should == 207
203
+ end
204
+ it 'returns 1066 for MLXVI' do
205
+ RomanNumber.new('MLXVI').convert_roman_to_decimal.should == 1066
206
+ end
207
+ it 'returns 44 for XLIV' do
208
+ RomanNumber.new('XLIV').convert_roman_to_decimal.should == 44
209
+ end
210
+ it 'returns 49 for XLIX' do
211
+ RomanNumber.new('XLIX').convert_roman_to_decimal.should == 49
212
+ end
213
+ it 'returns 904 for CMIV' do
214
+ RomanNumber.new('CMIV').convert_roman_to_decimal.should == 904
215
+ end
216
+ it 'returns 944 for CMXLIV' do
217
+ RomanNumber.new('CMXLIV').convert_roman_to_decimal.should == 944
218
+ end
219
+ it 'returns 1904 for MCMIV' do
220
+ RomanNumber.new('MCMIV').convert_roman_to_decimal.should == 1904
221
+ end
222
+ it 'returns 1944 for MCMXLIV' do
223
+ RomanNumber.new('MCMXLIV').convert_roman_to_decimal.should == 1944
224
+ end
225
+ it 'returns 30 for XXX' do
226
+ RomanNumber.new('XXX').convert_roman_to_decimal.should == 30
227
+ end
228
+ it 'returns 3999 for MMMCMXCIX' do
229
+ RomanNumber.new('MMMCMXCIX').convert_roman_to_decimal.should == 3999
230
+ end
231
+ end
232
+ context 'For Invalid Input' do
233
+ it 'raises InvalidInputError for ABCDE as input' do
234
+ expect {
235
+ RomanNumber.new('ABCDE').convert_roman_to_decimal
236
+ }.to raise_error(InvalidInputError)
237
+ end
238
+ it 'raises InvalidInputError for CCCCVII as input' do
239
+ expect {
240
+ RomanNumber.new('CCCCVII').convert_roman_to_decimal
241
+ }.to raise_error(InvalidInputError)
242
+ end
243
+ it 'raises InvalidInputError for CCVVVVI as input' do
244
+ expect {
245
+ RomanNumber.new('CCVVVVI').convert_roman_to_decimal
246
+ }.to raise_error(InvalidInputError)
247
+ end
248
+ end
249
+ end
250
+ end
251
+ end
252
+
@@ -0,0 +1,14 @@
1
+ # SimpleCov Settings
2
+ begin
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+ rescue LoadError
6
+ puts 'Coverage disabled, enable by installing simplecov'
7
+ end
8
+
9
+ # source
10
+ require_relative '../lib/roman_numbers'
11
+
12
+ # gems used
13
+ require 'rspec'
14
+ require 'awesome_print'
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roman_numbers
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Munish Goyal
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: awesome_print
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '1.2'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '1.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '2.14'
69
+ - !ruby/object:Gem::Dependency
70
+ name: autotest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: Conversion between Integers and Roman Numbers
98
+ email:
99
+ - munishapc@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - .rspec
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - autotest/discover.rb
111
+ - lib/roman_numbers.rb
112
+ - lib/roman_numbers/roman_number.rb
113
+ - lib/roman_numbers/version.rb
114
+ - roman_numbers.gemspec
115
+ - spec/roman_numbers/roman_number_spec.rb
116
+ - spec/spec_helper.rb
117
+ homepage: https://github.com/goyalmunish/roman_numbers
118
+ licenses:
119
+ - MIT
120
+ metadata: {}
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.1.11
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Conversion between Integers and Roman Numbers
141
+ test_files:
142
+ - spec/roman_numbers/roman_number_spec.rb
143
+ - spec/spec_helper.rb