Skip to content

Instantly share code, notes, and snippets.

@geronimod
Created November 22, 2013 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save geronimod/7602109 to your computer and use it in GitHub Desktop.
Save geronimod/7602109 to your computer and use it in GitHub Desktop.
Kata Roman Numbers
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