roman_monkey 1.0.0

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.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ *.gem
3
+ doc/
4
+ tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in roman_monkey.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Bardi Einarsson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,89 @@
1
+ roman\_monkey
2
+ ================
3
+
4
+ ## Summary
5
+
6
+ simple roman numerals from 1 to 3999
7
+
8
+ ## Description
9
+
10
+ roman\_monkey is a set of simple tools for formatting the numbers from 1 to 3999 as roman numerals, as well as, converting and validating the roman numerals themselves.
11
+
12
+ ## Usage
13
+
14
+ Object instance methods
15
+
16
+ require 'roman_monkey'
17
+ # or require 'fast_roman_monkey'
18
+ # for pre calculated roman numerals
19
+
20
+ :i_to_roman
21
+ :roman_to_i
22
+ :roman? # is it a roman numeral?, :roman_to_i equivalent
23
+
24
+ irb prompt> require 'roman_monkey'
25
+ => true
26
+ irb prompt> 1999.i_to_roman
27
+ => "MCMXCIX"
28
+ irb prompt> '1999 was a good year'.i_to_roman
29
+ => "MCMXCIX"
30
+ irb prompt> "MCMXCIX".roman_to_i
31
+ => 1999
32
+ irb prompt> :MCMXCIX.roman_to_i
33
+ => 1999
34
+ irb prompt> 'LD'.roman?
35
+ => nil
36
+ irb prompt> 'CDL'.roman?
37
+ => 450
38
+ irb prompt> 4000.i_to_roman
39
+ => nil
40
+ irb prompt> 0.i_to_roman
41
+ => nil
42
+
43
+ Simplest usage
44
+
45
+ require 'roman_numeral'
46
+ # for :i_to_roman module method
47
+
48
+ irb prompt> require 'roman_numeral'
49
+ => true
50
+ irb prompt> RomanNumeral.i_to_roman 3888
51
+ => "MMMDCCCLXXXVIII"
52
+
53
+ To add roman numeral validation
54
+
55
+ require 'slow_roman'
56
+ # for :roman_to_i module method
57
+ # or require 'fast_roman'
58
+ # for pre calculated roman numerals
59
+
60
+ irb prompt> require 'slow_roman'
61
+ => true
62
+ irb prompt> RomanNumeral.i_to_roman 3888
63
+ => "MMMDCCCLXXXVIII"
64
+ irb prompt> RomanNumeral.roman_to_i "MMMDCCCLXXXVIII"
65
+ => 3888
66
+
67
+ ## Requirements
68
+
69
+ Most likely any recent version of 1.9 ruby works.
70
+
71
+ ## Test with rspec ~> 2.11, rspec -fd
72
+
73
+ Try the software in irb:
74
+
75
+ irb prompt> load 'spec/support/roman_test.rb'
76
+
77
+ Note, to find the gem installation directory:
78
+
79
+ irb prompt> require 'roman_monkey'
80
+ irb prompt> $".grep(/roman_monkey/)[0]
81
+ irb prompt> Object.new.method(:i_to_roman).source_location
82
+ irb prompt> exit
83
+
84
+ ## License
85
+
86
+ Copyright (c) 2013 Bardi Einarsson. Released under the MIT License. See the [LICENSE][license] file for further details.
87
+
88
+ [license]: https://github.com/bardibardi/roman_monkey/blob/master/LICENSE.md
89
+
data/lib/fast_roman.rb ADDED
@@ -0,0 +1,20 @@
1
+ require_relative 'roman_numeral'
2
+
3
+ module RomanNumeral
4
+
5
+ ROMANS = (1...4000).reduce([nil],&->(a,i){a<<slow_i_to_roman(i).to_sym})
6
+ INTS = ROMANS.each_with_index.reduce({},&->(h,p){h[p[0]]=p[1];h})
7
+
8
+ def self.i_to_roman i
9
+ sym = ROMANS[i.to_i]
10
+ return nil unless sym
11
+ sym.to_s
12
+ end
13
+
14
+ def self.roman_to_i r
15
+ r = r.to_s.to_sym unless Symbol == r.class
16
+ INTS[r]
17
+ end
18
+
19
+ end
20
+
@@ -0,0 +1,18 @@
1
+ require_relative 'fast_roman'
2
+
3
+ class Object
4
+
5
+ def i_to_roman
6
+ RomanNumeral::i_to_roman self
7
+ end
8
+
9
+ def roman_to_i
10
+ RomanNumeral::roman_to_i self
11
+ end
12
+
13
+ def roman?
14
+ roman_to_i
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,18 @@
1
+ require_relative 'slow_roman'
2
+
3
+ class Object
4
+
5
+ def i_to_roman
6
+ RomanNumeral::i_to_roman self
7
+ end
8
+
9
+ def roman_to_i
10
+ RomanNumeral::roman_to_i self
11
+ end
12
+
13
+ def roman?
14
+ roman_to_i
15
+ end
16
+
17
+ end
18
+
@@ -0,0 +1,69 @@
1
+ module RomanNumeral
2
+
3
+ I_TO_DIGIT = {
4
+ 1 => :I,
5
+ 2 => :II,
6
+ 3 => :III,
7
+ 4 => :IV,
8
+ 5 => :V,
9
+ 6 => :VI,
10
+ 7 => :VII,
11
+ 8 => :VIII,
12
+ 9 => :IX,
13
+ 10 => :X,
14
+ 20 => :XX,
15
+ 30 => :XXX,
16
+ 40 => :XL,
17
+ 50 => :L,
18
+ 60 => :LX,
19
+ 70 => :LXX,
20
+ 80 => :LXXX,
21
+ 90 => :XC,
22
+ 100 => :C,
23
+ 200 => :CC,
24
+ 300 => :CCC,
25
+ 400 => :CD,
26
+ 500 => :D,
27
+ 600 => :DC,
28
+ 700 => :DCC,
29
+ 800 => :DCCC,
30
+ 900 => :CM,
31
+ 1000 => :M,
32
+ 2000 => :MM,
33
+ 3000 => :MMM
34
+ }
35
+
36
+ def self.high_digit_value i
37
+ return nil unless -1 < i
38
+ return [0, 0] if 0 == i
39
+ shift = 0
40
+ v = i
41
+ while v > 9
42
+ v = v/10
43
+ shift += 1
44
+ end
45
+ while shift > 0
46
+ v *= 10
47
+ shift -= 1
48
+ end
49
+ [v, i - v]
50
+ end
51
+
52
+ def self.i_to_roman i
53
+ r = []
54
+ rest = i.to_i
55
+ while (digit_value, rest = high_digit_value(rest); digit_value > 0)
56
+ roman_digit = I_TO_DIGIT[digit_value]
57
+ return nil unless roman_digit
58
+ r << roman_digit.to_s
59
+ end
60
+ return nil if 0 == r.length
61
+ r.join ''
62
+ end
63
+
64
+ class << self
65
+ alias :slow_i_to_roman :i_to_roman
66
+ end
67
+
68
+ end # RomanNumeral
69
+
data/lib/slow_roman.rb ADDED
@@ -0,0 +1,49 @@
1
+ require_relative 'roman_numeral'
2
+
3
+ module RomanNumeral
4
+
5
+ DIGIT_TO_I = I_TO_DIGIT.invert
6
+
7
+ def self.next_roman_digit_of_size r, size
8
+ len = r.length
9
+ rn = r.slice(0, size)
10
+ v = DIGIT_TO_I[rn.to_sym]
11
+ return nil unless v
12
+ tail = r.slice(size, len - size)
13
+ tail = nil if '' == tail
14
+ [v, tail]
15
+ end
16
+
17
+ def self.next_roman_digit r
18
+ result = next_roman_digit_of_size r, 4
19
+ return result if result
20
+ result = next_roman_digit_of_size r, 3
21
+ return result if result
22
+ result = next_roman_digit_of_size r, 2
23
+ return result if result
24
+ next_roman_digit_of_size r, 1
25
+ end
26
+
27
+ def self.roman_to_i r
28
+ return nil unless r
29
+ rest = r.to_s
30
+ return nil if 0 == rest.length
31
+ lastv = 10000
32
+ acc = 0
33
+ while rest
34
+ v, rest = next_roman_digit(rest)
35
+ return nil unless v
36
+ return nil unless lastv.to_s.length > v.to_s.length
37
+ acc += v
38
+ lastv = v
39
+ end
40
+ return nil if 0 == acc
41
+ acc
42
+ end
43
+
44
+ class << self
45
+ alias :slow_roman_to_i :roman_to_i
46
+ end
47
+
48
+ end # RomanNumeral
49
+
@@ -0,0 +1,30 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'roman_monkey'
3
+ s.version = '1.0.0'
4
+ s.date = '2013-04-07'
5
+ s.summary = "simple roman numerals from 1 to 3999"
6
+ s.description = "roman_monkey is a set of simple tools for formatting the numbers from 1 to 3999 as roman numerals, as well as, converting and validating the roman numerals themselves."
7
+
8
+ s.authors = ['Bardi Einarsson']
9
+ s.email = ['bardi@hotmail.com']
10
+ s.homepage = 'https://github.com/bardibardi/roman_monkey'
11
+ s.required_ruby_version = '>= 1.9.2'
12
+ s.add_development_dependency('rspec', '~> 2.11')
13
+
14
+ s.files = %w(
15
+ .gitignore
16
+ Gemfile
17
+ LICENSE.md
18
+ README.md
19
+ roman_monkey.gemspec
20
+ lib/roman_numeral.rb
21
+ lib/slow_roman.rb
22
+ lib/fast_roman.rb
23
+ lib/roman_monkey.rb
24
+ lib/fast_roman_monkey.rb
25
+ spec/roman_monkey_spec.rb
26
+ spec/support/no_should_rspec.rb
27
+ spec/support/roman_test.rb
28
+ )
29
+ end
30
+
@@ -0,0 +1,50 @@
1
+ require 'support/no_should_rspec'
2
+ require 'support/roman_test'
3
+
4
+ describe RomanNumeral do
5
+
6
+ it "should, for all roman numerals, convert integers to roman numerals and back" do
7
+ expect(RomanNumeral.reversible?).to be_true
8
+ end
9
+
10
+ it "should, for all roman numerals, slowly convert integers to roman numerals and back" do
11
+ expect(RomanNumeral.slow_reversible?).to be_true
12
+ end
13
+
14
+ end
15
+
16
+ describe Object do
17
+
18
+ it "should accept i_to_roman for number compatible types" do
19
+ expect(1.i_to_roman).to eq('I')
20
+ expect(1.9999.i_to_roman).to eq('I')
21
+ expect('1 potatoes'.i_to_roman).to eq('I')
22
+ expect(3999.i_to_roman).to eq('MMMCMXCIX')
23
+ expect('3999 marbles'.i_to_roman).to eq('MMMCMXCIX')
24
+ end
25
+
26
+ it "should accept roman_to_i for roman numeral compatible types" do
27
+ expect(:I.roman_to_i).to eq(1)
28
+ expect('I'.roman_to_i).to eq(1)
29
+ expect(:MMMCMXCIX.roman_to_i).to eq(3999)
30
+ expect('MMMCMXCIX'.roman_to_i).to eq(3999)
31
+ end
32
+
33
+ it "should have i_to_roman return null for instances not in (1...4000)" do
34
+ expect(0.i_to_roman).to be_nil
35
+ expect('no potatoes'.i_to_roman).to be_nil
36
+ expect(4000.0.i_to_roman).to be_nil
37
+ expect(4000.i_to_roman).to be_nil
38
+ expect('4000 marbles'.i_to_roman).to be_nil
39
+ end
40
+
41
+ it "should have roman_to_i return null for instances not in (:I..:MMMCDXCIX)" do
42
+ expect(''.roman_to_i).to be_nil
43
+ expect(nil.roman_to_i).to be_nil
44
+ expect(:MMMM.roman_to_i).to be_nil
45
+ expect(:CCD.roman_to_i).to be_nil
46
+ expect(:LM.roman_to_i).to be_nil
47
+ end
48
+
49
+ end
50
+
@@ -0,0 +1,9 @@
1
+ RSpec.configure do |config|
2
+
3
+ # rspec 2.11 turn off should monkey patching
4
+ config.expect_with :rspec do |c|
5
+ c.syntax = :expect
6
+ end
7
+
8
+ end
9
+
@@ -0,0 +1,54 @@
1
+ require_relative '../../lib/roman_monkey'
2
+ require_relative '../../lib/fast_roman'
3
+
4
+ module RomanNumeral
5
+
6
+ def self.reversible?
7
+ (1...4000).each do |i|
8
+ s = i_to_roman i
9
+ return nil unless s
10
+ i2 = roman_to_i s
11
+ return nil unless i2
12
+ return nil unless i == i2
13
+ end
14
+ true
15
+ end
16
+
17
+ def self.slow_reversible?
18
+ (1...4000).each do |i|
19
+ s = slow_i_to_roman i
20
+ return nil unless s
21
+ i2 = slow_roman_to_i s
22
+ return nil unless i2
23
+ return nil unless i == i2
24
+ end
25
+ true
26
+ end
27
+
28
+ def self.reversible2?
29
+ (1...4000).each do |i|
30
+ s = i_to_roman i
31
+ unless s
32
+ p 'i'
33
+ p i
34
+ return nil unless s
35
+ end
36
+ i2 = roman_to_i s
37
+ unless i2
38
+ p 's'
39
+ p s
40
+ return nil unless i2
41
+ end
42
+ unless i == i2
43
+ p 'i'
44
+ p i
45
+ p 'i2'
46
+ p i2
47
+ return nil unless i == i2
48
+ end
49
+ end
50
+ true
51
+ end
52
+
53
+ end # RomanNumeral
54
+
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: roman_monkey
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Bardi Einarsson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.11'
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: '2.11'
30
+ description: roman_monkey is a set of simple tools for formatting the numbers from
31
+ 1 to 3999 as roman numerals, as well as, converting and validating the roman numerals
32
+ themselves.
33
+ email:
34
+ - bardi@hotmail.com
35
+ executables: []
36
+ extensions: []
37
+ extra_rdoc_files: []
38
+ files:
39
+ - .gitignore
40
+ - Gemfile
41
+ - LICENSE.md
42
+ - README.md
43
+ - roman_monkey.gemspec
44
+ - lib/roman_numeral.rb
45
+ - lib/slow_roman.rb
46
+ - lib/fast_roman.rb
47
+ - lib/roman_monkey.rb
48
+ - lib/fast_roman_monkey.rb
49
+ - spec/roman_monkey_spec.rb
50
+ - spec/support/no_should_rspec.rb
51
+ - spec/support/roman_test.rb
52
+ homepage: https://github.com/bardibardi/roman_monkey
53
+ licenses: []
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: 1.9.2
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 1.8.25
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: simple roman numerals from 1 to 3999
76
+ test_files: []