roman_numbers 0.0.5 → 0.0.6

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: 154520d9143e2297d9ca4437b70f1eb36de4cf57
4
- data.tar.gz: 6764dcb2c45acd10300909022016e5c400708ef8
3
+ metadata.gz: 19a16ed12f582cd4cf0facf87dfb249da2090d44
4
+ data.tar.gz: 6e46b7f767a96b8aa9e75f3800211edb22c93dd1
5
5
  SHA512:
6
- metadata.gz: 2c0d2b3fb03daaed1778de72df60e8f94f1496870073a3111998f1fcec225e9366d8830fedfa4f1e966d8f7a16eaf1f7c55d42d680cc351f15e6e131704f12ee
7
- data.tar.gz: 1bb43845ca739c2ebded476deb5d8088a199458edbdd1797e3675c1856cc3946c2b95ac6d51583d710b1bb69ef8a744dbff9b1110fdf27fa3e26a7459e736dd4
6
+ metadata.gz: 0ea20220716f648aa0c48f623e24fcbd6933ba4c3d9f3cb91c20d143a0f8e2e2b3b27e39439daf48e99c4173d1f7b02d67b4dfc7f2b5bc563ae976399f43e31b
7
+ data.tar.gz: 64a0f5f5bacf1c0542f11172758d36d0adc1ee6e46aee5794c171aab0d81b20224ea4ff00e81f7e7aef52791bbbeab3eeca0fab49333e7850aefd50a3183ee3b
@@ -43,28 +43,29 @@ module RomanNumbers
43
43
  @output_roman = String.new
44
44
  when String
45
45
  @input_string = input.upcase
46
- @output_arabic = 0
46
+ @output_integer = 0
47
47
  end
48
48
  end
49
49
 
50
+ attr_accessor :input_integer, :input_string, :output_roman, :staged_roman_hash, :output_integer
51
+
50
52
  # converts arabic to roman
51
- def convert_decimal_to_roman(input_integer=@input_integer)
53
+ def convert_decimal_to_roman(passed_integer=input_integer)
52
54
  # validating input
53
- unless (1..3999).include? input_integer
54
- raise InvalidInputError, "Invalid Input: #{input_integer}"
55
+ unless (1..3999).include? passed_integer
56
+ raise InvalidInputError, "Invalid Input: #{passed_integer}"
55
57
  end
56
58
  # getting staged roman hash
57
- calculate_staged_roman_hash(input_integer)
59
+ calculate_staged_roman_hash(passed_integer)
58
60
  # 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
+ staged_roman_hash.each do |element|
62
+ output_roman << (element[:largest_element][:unit].to_s)*(element[:times])
61
63
  end
62
- return @output_roman
64
+ output_roman
63
65
  end
64
66
 
65
67
  # 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
+ def convert_roman_to_decimal(passed_roman=input_string.clone)
68
69
  # generating regex expressions
69
70
  double_units_array = ROMAN_NON_REPEATABLE_UNITS_2.map { |element| ('^' + element[:unit].to_s) }
70
71
  single_units_array = (ROMAN_REPEATABLE_UNITS + ROMAN_NON_REPEATABLE_UNITS_1).map { |element| ('^' + element[:unit].to_s) }
@@ -72,94 +73,95 @@ module RomanNumbers
72
73
  single_units_regex = Regexp.new(single_units_array.join('|'))
73
74
  # validation
74
75
  # TODO: to add more validations
75
- if input_roman =~ /(.)\1{#{MAX_ALLOWED_REPETITION},}/
76
- raise InvalidInputError, "Invalid Input: #{input_roman}"
76
+ if passed_roman =~ /(.)\1{#{MAX_ALLOWED_REPETITION},}/
77
+ raise InvalidInputError, "Invalid Input: #{passed_roman}"
77
78
  end
78
79
  # 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)
80
+ if passed_roman.length > 0
81
+ if unit = passed_roman.slice!(double_units_regex)
82
+ self.output_integer += ROMAN_DOUBLE_UNITS.find { |element| element[:unit] == unit.to_sym }[:value]
83
+ convert_roman_to_decimal(passed_roman)
84
+ elsif unit = passed_roman.slice!(single_units_regex)
85
+ self.output_integer += ROMAN_SINGLE_UNITS.find { |element| element[:unit] == unit.to_sym }[:value]
86
+ convert_roman_to_decimal(passed_roman)
86
87
  else
87
- # invalud input
88
- raise InvalidInputError, "Invalid Input: #{input_roman}"
88
+ # invalid input
89
+ raise InvalidInputError, "Invalid Input: #{passed_roman}"
89
90
  end
90
91
  else
91
92
  # process is complete
92
- return @output_arabic
93
+ self.output_integer
93
94
  end
94
-
95
95
  end
96
96
 
97
+ protected :input_integer, :input_string, :output_roman, :staged_roman_hash, :output_integer
98
+
97
99
  private
98
100
 
99
101
  # returns an array of hashed containing info on desired output roman
100
- def calculate_staged_roman_hash(input_integer)
102
+ def calculate_staged_roman_hash(passed_input_integer)
101
103
  begin
102
- temp_hash = largest_repeatable_element(input_integer)
104
+ temp_hash = largest_repeatable_element(passed_input_integer)
103
105
  rescue StartsWithNonRepeatableRomanUnitError => ex
104
- temp_hash = largest_non_repeatable_element(input_integer)
106
+ temp_hash = largest_non_repeatable_element(passed_input_integer)
105
107
  end
106
108
  if temp_hash
107
- @staged_roman_hash << temp_hash
108
- input_integer = temp_hash[:reduced_integer]
109
- calculate_staged_roman_hash(input_integer)
109
+ staged_roman_hash << temp_hash
110
+ passed_input_integer = temp_hash[:reduced_integer]
111
+ calculate_staged_roman_hash(passed_input_integer)
110
112
  else
111
113
  # processing done
112
- return @staged_roman_hash
114
+ staged_roman_hash
113
115
  end
114
116
  end
115
117
 
116
118
  # returns reduced_integer, largest repeatable element, and number of times it can be repeated
117
- def largest_repeatable_element(input_integer)
118
- if input_integer > 0
119
- largest_element = ROMAN_REPEATABLE_UNITS.find { |element| input_integer >= element[:value] }
119
+ def largest_repeatable_element(passed_input_integer)
120
+ if passed_input_integer > 0
121
+ largest_element = ROMAN_REPEATABLE_UNITS.find { |element| passed_input_integer >= element[:value] }
120
122
  # TODO: make it efficient by removing elements before largest_element
121
123
  # TODO: to use binary search instead
122
124
  if largest_element
123
- times = input_integer/largest_element[:value]
124
- reduced_integer = input_integer%largest_element[:value]
125
+ times = passed_input_integer/largest_element[:value]
126
+ reduced_integer = passed_input_integer%largest_element[:value]
125
127
  if times > MAX_ALLOWED_REPETITION
126
128
  # given integer starts with non_repeatable roman unit
127
129
  raise StartsWithNonRepeatableRomanUnitError
128
130
  end
129
- return {:reduced_integer => reduced_integer, :largest_element => largest_element, :times => times}
131
+ {:reduced_integer => reduced_integer, :largest_element => largest_element, :times => times}
130
132
  else
131
133
  # non-reachable code
132
134
  raise NonReachableCodeError, 'LargestElementIsNil'
133
135
  end
134
- elsif input_integer == 0
136
+ elsif passed_input_integer == 0
135
137
  # process completed
136
- return nil
138
+ nil
137
139
  else
138
140
  # non-reachable code
139
- # input_integer has to be >=0
141
+ # passed_input_integer has to be >=0
140
142
  raise NonReachableCodeError, 'ReceivedNegativeInteger'
141
143
  end
142
144
  end
143
145
 
144
146
  # returns largest non-repeatable element
145
- def largest_non_repeatable_element(input_integer)
146
- if input_integer > 0
147
- largest_element = ROMAN_NON_REPEATABLE_UNITS.find { |element| input_integer >= element[:value] }
147
+ def largest_non_repeatable_element(passed_input_integer)
148
+ if passed_input_integer > 0
149
+ largest_element = ROMAN_NON_REPEATABLE_UNITS.find { |element| passed_input_integer >= element[:value] }
148
150
  # TODO: make it efficient by removing elements before largest_element
149
151
  # TODO: to use binary search instead
150
152
  if largest_element
151
- reduced_integer = input_integer%largest_element[:value]
152
- return {:reduced_integer => reduced_integer, :largest_element => largest_element, :times => 1}
153
+ reduced_integer = passed_input_integer%largest_element[:value]
154
+ {:reduced_integer => reduced_integer, :largest_element => largest_element, :times => 1}
153
155
  else
154
156
  # no non_repeatable element preset, but process is not complete yet
155
- return {:reduced_integer => input_integer, :largest_element => nil, :times => 0}
157
+ {:reduced_integer => passed_input_integer, :largest_element => nil, :times => 0}
156
158
  end
157
- elsif input_integer == 0
159
+ elsif passed_input_integer == 0
158
160
  # process completed
159
- return nil
161
+ nil
160
162
  else
161
163
  # non-reachable code
162
- # input_integer has to be >=0
164
+ # passed_input_integer has to be >=0
163
165
  raise NonReachableCodeError, 'ReceivedNegativeInteger'
164
166
  end
165
167
  end
@@ -1,3 +1,3 @@
1
1
  module RomanNumbers
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
@@ -0,0 +1,13 @@
1
+ require_relative './spec_helper'
2
+ include RomanNumbers
3
+
4
+ describe Integer do
5
+
6
+ context "#to_roman" do
7
+
8
+ it "is added and internally calls 'convert_decimal_to_roman'" do
9
+ expect_any_instance_of(RomanNumbers::RomanNumber).to receive(:convert_decimal_to_roman)
10
+ 7999112.to_roman
11
+ end
12
+ end
13
+ end
@@ -10,15 +10,40 @@ module RomanNumbers
10
10
  end
11
11
 
12
12
  describe '#convert_decimal_to_roman' do
13
- shared_examples_for "works_with_valid_integral_roman_input_collection" do |array|
13
+ shared_examples_for "works_with_valid_integral_input_and_roman_output_collection" do |array|
14
14
  # Note: here array is array of hashes
15
15
  array.each do |hsh|
16
- it %Q{returns #{hsh[:integer]} for #{hsh[:roman]} as input} do
16
+ it %Q{returns #{hsh[:roman]} for #{hsh[:integer]} as input} do
17
17
  RomanNumber.new(hsh[:integer]).convert_decimal_to_roman.should == hsh[:roman]
18
18
  end
19
19
  end
20
20
  end
21
-
21
+
22
+ context 'For Following Valid Inputs' do
23
+ it_behaves_like "works_with_valid_integral_input_and_roman_output_collection", Helpers.valid_inputs
24
+ end
25
+
26
+ context 'For Following Invalid Input' do
27
+ [4000, 0, -10, '10'].each do |exp_input|
28
+ it %Q{raises #{$invalid_input_error} for #{exp_input} as input} do
29
+ expect {
30
+ RomanNumber.new(exp_input).convert_decimal_to_roman
31
+ }.to raise_error($invalid_input_error)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ describe '#convert_roman_to_decimal' do
38
+ shared_examples_for "works_with_valid_roman_input_and_integral_output_collection" do |array|
39
+ # Note: here array is array of hashes
40
+ array.each do |hsh|
41
+ it %Q{returns #{hsh[:integer]} for #{hsh[:roman]} as input} do
42
+ RomanNumber.new(hsh[:roman]).convert_roman_to_decimal.should == hsh[:integer]
43
+ end
44
+ end
45
+ end
46
+
22
47
  shared_examples_for "raises_error_on_invalid_roman_input_collection" do |array|
23
48
  # Note: here array is array of integers
24
49
  array.each do |integral_elem|
@@ -26,7 +51,7 @@ module RomanNumbers
26
51
  expect {
27
52
  RomanNumber.new(integral_elem).convert_decimal_to_roman
28
53
  }.to raise_error($invalid_input_error)
29
- end
54
+ end
30
55
  end
31
56
  end
32
57
 
@@ -35,17 +60,17 @@ module RomanNumbers
35
60
  end
36
61
 
37
62
  context %q(Symbols 'I', 'X', 'C', and 'M' can be repeated 4 times if 3rd and 4th are separated by smaller value) do
38
- it_behaves_like "works_with_valid_integral_roman_input_collection", Helpers.input_set_1
63
+ it_behaves_like "works_with_valid_roman_input_and_integral_output_collection", Helpers.input_set_1
39
64
  end
40
65
 
41
66
  context %q(Symbols 'D', 'L', 'V' can never be repeated in succession) do
42
67
  it_behaves_like "raises_error_on_invalid_roman_input_collection", %w(DD DDC LL LLX VV VVI)
43
68
  end
44
69
 
45
- context %Q(Symbol 'I' can be subtrated from 'V' and 'X', and
70
+ context %Q(Symbol 'I' can be subtracted from 'V' and 'X', and
46
71
  Symbol 'L' can be subtracted from 'L' and 'C', and
47
72
  Symbol 'C' can be subtracted from 'D' and 'M') do
48
- it_behaves_like "works_with_valid_integral_roman_input_collection", Helpers.input_set_2
73
+ it_behaves_like "works_with_valid_roman_input_and_integral_output_collection", Helpers.input_set_2
49
74
  end
50
75
 
51
76
  context %Q(Symbol 'I' can be subtrated from 'V' and 'X' only, and
@@ -53,23 +78,7 @@ module RomanNumbers
53
78
  Symbol 'C' can be subtracted from 'D' and 'M' only) do
54
79
  it_behaves_like "raises_error_on_invalid_roman_input_collection", %w(IL IC ID IM XD XM)
55
80
  end
56
-
57
- context 'For Following Valid Inputs' do
58
- it_behaves_like "works_with_valid_integral_roman_input_collection", Helpers.valid_inputs
59
- end
60
-
61
- context 'For Following Invalid Input' do
62
- [4000, 0, -10, '10'].each do |exp_input|
63
- it %Q{raises #{$invalid_input_error} for #{exp_input} as input} do
64
- expect {
65
- RomanNumber.new(exp_input).convert_decimal_to_roman
66
- }.to raise_error($invalid_input_error)
67
- end
68
- end
69
- end
70
- end
71
81
 
72
- describe '#convert_roman_to_decimal' do
73
82
  context 'For Valid Input' do
74
83
  Helpers.valid_inputs.each do |hsh|
75
84
  it %Q{returns #{hsh[:roman]} for #{hsh[:integer]} as input} do
@@ -0,0 +1,13 @@
1
+ require_relative './spec_helper'
2
+ include RomanNumbers
3
+
4
+ describe String do
5
+
6
+ context "#from_roman_to_integer" do
7
+
8
+ it "is added and internally calls 'convert_roman_to_decimal'" do
9
+ expect_any_instance_of(RomanNumbers::RomanNumber).to receive(:convert_roman_to_decimal)
10
+ "some_string".from_roman_to_integer
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roman_numbers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Munish Goyal
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-02 00:00:00.000000000 Z
11
+ date: 2015-05-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -113,8 +113,10 @@ files:
113
113
  - lib/roman_numbers/version.rb
114
114
  - roman_numbers.gemspec
115
115
  - spec/helpers.rb
116
+ - spec/integer_spec.rb
116
117
  - spec/roman_numbers/roman_number_spec.rb
117
118
  - spec/spec_helper.rb
119
+ - spec/string_spec.rb
118
120
  homepage: https://github.com/goyalmunish/roman_numbers
119
121
  licenses:
120
122
  - MIT
@@ -142,5 +144,7 @@ summary: Conversion between Integers and Roman Numbers
142
144
  test_files:
143
145
  - autotest/discover.rb
144
146
  - spec/helpers.rb
147
+ - spec/integer_spec.rb
145
148
  - spec/roman_numbers/roman_number_spec.rb
146
149
  - spec/spec_helper.rb
150
+ - spec/string_spec.rb