-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
df5a0f7
commit 99d5cf0
Showing
155 changed files
with
11,233 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
require "rspec" | ||
|
||
class String | ||
|
||
ROMAN_ARABIC_TRANSLATION = [["M", 1000], | ||
["CM",900], | ||
["D", 500], | ||
["CD",400], | ||
["C", 100], | ||
["XC",90], | ||
["L", 50], | ||
["XL",40], | ||
["X", 10], | ||
["IX",9], | ||
["V", 5], | ||
["IV",4], | ||
["I", 1]] | ||
|
||
def to_arabic | ||
roman_number_to_convert = self | ||
ROMAN_ARABIC_TRANSLATION.each do |roman,arabic| | ||
if roman_number_to_convert.start_with? roman | ||
return arabic if roman == roman_number_to_convert | ||
return arabic + roman_number_without_the_first(roman).to_arabic | ||
end | ||
end | ||
end | ||
|
||
def roman_number_without_the_first(roman) | ||
|
||
self[roman.size,self.size-1] | ||
|
||
end | ||
|
||
end | ||
|
||
|
||
describe "roman to arabic number converter" do | ||
|
||
it "transform one roman character to arabic" do | ||
"I".to_arabic.should == 1 | ||
"V".to_arabic.should == 5 | ||
"X".to_arabic.should == 10 | ||
"L".to_arabic.should == 50 | ||
"C".to_arabic.should == 100 | ||
"D".to_arabic.should == 500 | ||
"M".to_arabic.should == 1000 | ||
end | ||
|
||
it "transform special cases with two roman characters, where the first is substracting the second, to arabic" do | ||
"IV".to_arabic.should == 4 | ||
"IX".to_arabic.should == 9 | ||
"XL".to_arabic.should == 40 | ||
"XC".to_arabic.should == 90 | ||
"CD".to_arabic.should == 400 | ||
"CM".to_arabic.should == 900 | ||
end | ||
|
||
it "transform two and three equal roman characters to arabic" do | ||
"II".to_arabic.should == 2 | ||
"III".to_arabic.should == 3 | ||
end | ||
|
||
it "transform complex roman numbers to arabic" do | ||
"XIV".to_arabic.should == 14 | ||
"XLIX".to_arabic.should == 49 | ||
"MCMXCIX".to_arabic.should == 1999 | ||
end | ||
|
||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
''' | ||
Created on 01/03/2011 | ||
@author: Fergus | ||
''' | ||
class Numerals: | ||
|
||
def __init__(self): | ||
self.romanos = {"I" : 1, "V":5, "X":10, | ||
"L":50, "C":100, "D":500, "M":1000} | ||
self.numeros = {1 : "I", 5:"V", 10:"X", | ||
50:"L", 100:"C", 500:"D", 1000:"M"} | ||
self.tuplaNumeros=(1000,500,100,50,10,5,1) | ||
def romanoANumero(self, parametro): | ||
'Invertir orden' | ||
parametro=parametro[::-1] | ||
'Recorrer numero romano' | ||
mayor="I" | ||
resultado=0 | ||
for letraSeleccionada in parametro: | ||
if self.romanos[mayor] <= self.romanos[letraSeleccionada]: | ||
resultado = resultado + self.romanos[letraSeleccionada] | ||
mayor = letraSeleccionada | ||
else: | ||
resultado = resultado - self.romanos[letraSeleccionada] | ||
return resultado | ||
def numeroARomano(self, parametro): | ||
resultado="" | ||
for numero in self.tuplaNumeros: | ||
cociente=parametro//numero; | ||
parametro=parametro-(parametro//numero)*numero | ||
while cociente>0: | ||
resultado = resultado + self.numeros[numero] | ||
cociente = cociente - 1 | ||
resultado=resultado.replace("IIII", "IV") | ||
resultado=resultado.replace("VIV", "IX") | ||
resultado=resultado.replace("XXXX", "XL") | ||
resultado=resultado.replace("XXXX", "XL") | ||
resultado=resultado.replace("LXL", "XC") | ||
resultado=resultado.replace("CCCC", "CD") | ||
resultado=resultado.replace("DCD", "CM") | ||
return resultado | ||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
''' | ||
Created on 01/03/2011 | ||
@author: Fergus | ||
''' | ||
|
||
import unittest | ||
from Numerals import Numerals | ||
|
||
class Tests(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.numerals = Numerals() | ||
|
||
def testGlobal(self): | ||
self.dobleConversion("I",1) | ||
self.dobleConversion("II", 2) | ||
self.dobleConversion("III",3) | ||
self.dobleConversion("IV",4) | ||
self.dobleConversion("V",5) | ||
self.dobleConversion("VI",6) | ||
self.dobleConversion("VII",7) | ||
self.dobleConversion("VIII",8) | ||
self.dobleConversion("IX",9) | ||
self.dobleConversion("X",10) | ||
self.dobleConversion("XI",11) | ||
self.dobleConversion("XII",12) | ||
self.dobleConversion("XV",15) | ||
self.dobleConversion("XX",20) | ||
self.dobleConversion("XXX",30) | ||
self.dobleConversion("XXXIX",39) | ||
self.dobleConversion("XL",40) | ||
self.dobleConversion("XLI",41) | ||
self.dobleConversion("XLV",45) | ||
self.dobleConversion("L",50) | ||
self.dobleConversion("LX",60) | ||
self.dobleConversion("LXX",70) | ||
self.dobleConversion("LXXX",80) | ||
self.dobleConversion("XC",90) | ||
self.dobleConversion("LXIX",69) | ||
self.dobleConversion("XCIX",99) | ||
self.dobleConversion("CDL",450) | ||
self.dobleConversion("DCLXVI",666) | ||
self.dobleConversion("CMXCIX",999) | ||
self.dobleConversion("MCDXLIV",1444) | ||
self.dobleConversion("MCM",1900) | ||
self.dobleConversion("MMVIII",2008) | ||
self.dobleConversion("MMIX",2009) | ||
self.dobleConversion("MMXI",2011) | ||
self.dobleConversion("MMXII",2012) | ||
self.dobleConversion("MMXIII",2013) | ||
self.dobleConversion("MMXIV",2014) | ||
self.dobleConversion("MMXV",2015) | ||
self.dobleConversion("MMXVI",2016) | ||
|
||
def dobleConversion(self, romano, numero): | ||
mensaje = "Error al pasar " + str(romano) + " a " + str(numero) + "; resultado = " + str(self.numerals.romanoANumero(romano)) | ||
self.assertEquals(self.numerals.romanoANumero(romano),numero,mensaje) | ||
mensaje = "Error al pasar " + str(numero) + " a " + str(romano) + "; resultado = " + str(self.numerals.numeroARomano(numero)) | ||
self.assertEquals(self.numerals.numeroARomano(numero),romano,mensaje) | ||
|
||
if __name__ == "__main__": | ||
unittest.main() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
Problem Description | ||
|
||
The Romans were a clever bunch. They conquered most of Europe and ruled it for hundreds of years. They invented concrete and straight roads and even bikinis[1]. One thing they never discovered though was the number zero. This made writing and dating extensive histories of their exploits slightly more challenging, but the system of numbers they came up with is still in use today. For example the BBC uses Roman numerals to date their programmes. | ||
|
||
The Romans wrote numbers using letters - I, V, X, L, C, D, M. (notice these letters have lots of straight lines and are hence easy to hack into stone tablets) | ||
|
||
The Kata says you should write a function to convert from normal numbers to Roman Numerals: eg | ||
|
||
1 --> I | ||
10 --> X | ||
7 --> VII | ||
etc. | ||
For a full description of how it works, take a look at [http://www.novaroma.org/via_romana/numbers.html]: which includes an implementation of the Kata in javascript. | ||
|
||
There is no need to be able to convert numbers larger than about 3000. (The Romans themselves didn't tend to go any higher) | ||
|
||
Note that you can't write numerals like "IM" for 999. Wikipedia says: Modern Roman numerals ... are written by expressing each digit separately starting with the left most digit and skipping any digit with a value of zero. To see this in practice, consider the ... example of 1990. In Roman numerals 1990 is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC. 2008 is written as 2000=MM, 8=VIII; or MMVIII. | ||
|
||
Part II of the Kata | ||
|
||
Write a function to convert in the other direction, ie numeral to digit | ||
Clues | ||
|
||
can you make the code really beautiful and highly readable? | ||
* does it help to break out lots of small named functions from the main function, or is it better to keep it all in one function? | ||
if you don't know an algorithm to do this already, can you derive one using strict TDD? | ||
* does the order you take the tests in affect the final design of your algorithm? | ||
* Would it be better to work out an algorithm first before starting with TDD? | ||
if you do know an algorithm already, can you implement it using strict TDD? | ||
* Can you think of another algorithm? | ||
what are the best data structures for storing all the numeral letters? (I, V, D, M etc) | ||
can you define the test cases in a csv file and use FIT, or generate test cases in xUnit? | ||
what is the best way to verify your tests are correct? | ||
Suggested Test Cases | ||
|
||
Exercise left to the reader. You could use 1999 as an acceptance test. | ||
|
||
URL: http://codingdojo.org/cgi-bin/wiki.pl?KataRomanNumerals |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/usr/bin/python | ||
|
||
class NumericToRomanParser: | ||
|
||
def __init__(self): | ||
self.rosettaStone = { | ||
1:'I', | ||
5:'V', | ||
10:'X', | ||
50:'L', | ||
100:'C', | ||
500:'D', | ||
1000:'M' | ||
} | ||
|
||
def getRomanNumber(self, number): | ||
if (number in self.rosettaStone): | ||
return self.rosettaStone[number] | ||
elif number > 1000: | ||
return 'M'+self.getRomanNumber(number-1000) | ||
elif number > 500: | ||
return 'D'+self.getRomanNumber(number-500) | ||
elif number > 100: | ||
return 'C'+self.getRomanNumber(number-100) | ||
elif number > 50: | ||
return 'L'+self.getRomanNumber(number-50) | ||
elif number > 10: | ||
return 'X'*(number/10)+self.getRomanNumber(number%10) | ||
elif number > 5: | ||
return 'V'+'I'*(number-5) | ||
else: | ||
return 'I'*number | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#!/usr/bin/python | ||
|
||
import unittest | ||
from roman_numerals import NumericToRomanParser | ||
|
||
class NumericToRomanParserTestCase(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.parser = NumericToRomanParser() | ||
|
||
def testMainSymbols(self): | ||
self.assertEqual(self.parser.getRomanNumber(1), 'I') | ||
self.assertEqual(self.parser.getRomanNumber(5), 'V') | ||
self.assertEqual(self.parser.getRomanNumber(10), 'X') | ||
self.assertEqual(self.parser.getRomanNumber(50), 'L') | ||
self.assertEqual(self.parser.getRomanNumber(100), 'C') | ||
self.assertEqual(self.parser.getRomanNumber(500), 'D') | ||
self.assertEqual(self.parser.getRomanNumber(1000), 'M') | ||
|
||
def testNumbersLowerThanFive(self): | ||
self.assertEqual(self.parser.getRomanNumber(2), 'II') | ||
self.assertEqual(self.parser.getRomanNumber(3), 'III') | ||
self.assertEqual(self.parser.getRomanNumber(4), 'IIII') | ||
|
||
def testNumbersBetweenFiveAndTen(self): | ||
self.assertEqual(self.parser.getRomanNumber(6), 'VI') | ||
self.assertEqual(self.parser.getRomanNumber(7), 'VII') | ||
self.assertEqual(self.parser.getRomanNumber(8), 'VIII') | ||
self.assertEqual(self.parser.getRomanNumber(9), 'VIIII') | ||
|
||
def testNumbersBetweenXAndL(self): | ||
self.assertEqual(self.parser.getRomanNumber(11), 'XI') | ||
self.assertEqual(self.parser.getRomanNumber(15), 'XV') | ||
self.assertEqual(self.parser.getRomanNumber(23), 'XXIII') | ||
self.assertEqual(self.parser.getRomanNumber(29), 'XXVIIII') | ||
|
||
def testMeaningOfLife(self): | ||
self.assertEqual(self.parser.getRomanNumber(42), 'XXXXII') | ||
|
||
def testNumbersBetweenLAndC(self): | ||
self.assertEqual(self.parser.getRomanNumber(51), 'LI') | ||
self.assertEqual(self.parser.getRomanNumber(99), 'LXXXXVIIII') | ||
|
||
def testNumbersBetweenCAndD(self): | ||
self.assertEqual(self.parser.getRomanNumber(105), 'CV') | ||
self.assertEqual(self.parser.getRomanNumber(205), 'CCV') | ||
self.assertEqual(self.parser.getRomanNumber(399), 'CCCLXXXXVIIII') | ||
|
||
def testNumbersBetweenDAndM(self): | ||
self.assertEqual(self.parser.getRomanNumber(501), 'DI') | ||
|
||
def testNumbersBetweenMAndMMM(self): | ||
self.assertEqual(self.parser.getRomanNumber(1999), 'MDCCCCLXXXXVIIII') | ||
self.assertEqual(self.parser.getRomanNumber(2956), 'MMDCCCCLVI') | ||
|
||
if __name__ == '__main__': | ||
unittest.main() |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
La kata ha sido realizada con recursividad | ||
|
||
La funcion recursiva mantiene el numero a tratar y el tama�o de la string del n�mero a efectos de decidir si los 1s y los 5s se traducen a Is, Xs, Cs o Ms y a Vs, Ls o Ds, respectivamente | ||
|
||
Estoy abierto a comentarios. | ||
|
||
Gracias |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.idea | ||
target | ||
*.iml |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Implementación de la Kata de números romanos | ||
============================================ | ||
|
||
Lenguaje: Ruby | ||
Pruebas: Cucumber + RSpec | ||
Estilo: Sin hashes con números romanos "extra" (IX, IV, etc…). | ||
|
||
-- | ||
amuino |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
class Fixnum | ||
ROMAN_ONES = ["I", "X", "C", "M"] | ||
ROMAN_FIVES = ["V", "L", "D", ""] | ||
|
||
def to_roman | ||
return nil if self < 1 || self >= 4000 | ||
current = self | ||
[3,2,1,0].inject("") do |result, power| | ||
div, mod = current.divmod(10**power) | ||
current = mod | ||
result + digit_to_roman(div, power) | ||
end | ||
end | ||
|
||
def digit_to_roman(digit, scale) | ||
five_or_more, less_than_five = digit.divmod(5) | ||
case less_than_five | ||
when 4 then ROMAN_ONES[scale] + (five_or_more == 1 ? ROMAN_ONES[scale+1] : ROMAN_FIVES[scale]) | ||
else ROMAN_FIVES[scale]*five_or_more + ROMAN_ONES[scale]*less_than_five | ||
end | ||
end | ||
end | ||
|
||
class String | ||
ROMAN_VALUES = {"M" => 1000, "D" => 500, "C" => 100, "L" => 50, "X" => 10, "V" => 5, "I" => 1} | ||
|
||
def from_roman | ||
integer = (self.chars.to_a << nil).each_cons(2).inject(0) do |result, digits| | ||
current_digit, next_digit = from_roman_letter(digits.first), from_roman_letter(digits.last).to_i | ||
return nil if current_digit.nil? || next_digit.nil? | ||
sign = (current_digit < next_digit) ? -1 : +1 | ||
result += sign * current_digit | ||
end | ||
return integer if integer.to_roman == self | ||
nil | ||
end | ||
|
||
def from_roman_letter(value) | ||
return ROMAN_VALUES[value] | ||
end | ||
end |
Oops, something went wrong.