Created
November 22, 2013 15:53
-
-
Save geronimod/7602109 to your computer and use it in GitHub Desktop.
Kata Roman Numbers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'minitest/autorun' | |
class Integer | |
# rules: | |
# - Si a la derecha de una cifra romana de escribe otra igual o menor, el valor de ésta se suma a la anterior. | |
# - La cifra "I" colocada delante de la "V" o la "X", les resta una unidad; la "X", precediendo a la "L" o a la "C", les resta diez unidades y la "C", delante de la "D" o la "M", les resta cien unidades. | |
# - En ningún número se puede poner una misma letra más de tres veces seguidas. En la antigüedad se ve a veces la "I" o la "X" hasta cuatro veces seguidas. | |
# - La "V", la "L" y la "D" no pueden duplicarse porque otras letras ("X", "C", "M") representan su valor duplicado. | |
# - Si entre dos cifras cualesquiera existe otra menor, ésta restará su valor a la siguiente. | |
ROMAN = { | |
1 => 'I', | |
5 => 'V', | |
10 => 'X', | |
50 => 'L', | |
100 => 'C', | |
500 => 'D', | |
1000 => 'M' | |
} | |
P = { | |
'I' => 'V', | |
'X' => 'L', | |
'C' => 'D' | |
} | |
def to_roman | |
''.tap do |roman| | |
_self = self | |
ROMAN.keys.reverse.each do |div| | |
r, _self = _self.divmod div | |
letter = ROMAN[div] | |
roman << (r > 3 && P[letter] ? letter + P[letter] : letter * r) | |
roman.sub!(/#{P[letter]}(.)#{P[letter]}/) { $1 + multiple(P[letter]) } if P[letter] && multiple(P[letter]) | |
end | |
end | |
end | |
def multiple(l) | |
ROMAN[ROMAN.key(l) * 2] | |
end | |
private :multiple | |
end | |
describe 'Roman Numbers' do | |
it "must to return the roman number equivalent" do | |
1.to_roman.must_equal 'I' | |
2.to_roman.must_equal 'II' | |
3.to_roman.must_equal 'III' | |
4.to_roman.must_equal 'IV' | |
5.to_roman.must_equal 'V' | |
6.to_roman.must_equal 'VI' | |
7.to_roman.must_equal 'VII' | |
8.to_roman.must_equal 'VIII' | |
9.to_roman.must_equal 'IX' | |
10.to_roman.must_equal 'X' | |
50.to_roman.must_equal 'L' | |
500.to_roman.must_equal 'D' | |
1000.to_roman.must_equal 'M' | |
49.to_roman.must_equal 'XLIX' | |
99.to_roman.must_equal 'XCIX' | |
999.to_roman.must_equal 'CMXCIX' | |
18273.to_roman.must_equal 'MMMMMMMMMMMMMMMMMMCCLXXIII' | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment