Solution to Kata "Roman Calculator" http://codingdojo.org/cgi-bin/wiki.pl?KataRomanCalculator @CarlosCondor @robermorales
public class Calculator {
public static String[][] values = {
{ "CM", "DCD" },
{ "M", "DD" },
{ "CD", "CCCC" },
{ "D", "CCCCC" },
{ "XC", "LXL" },
{ "C", "LL" },
{ "XL", "XXXX" },
{ "L", "XXXXX" },
{ "IX", "VIV" },
{ "X", "VV" },
{ "IV", "IIII" },
{ "V", "IIIII" }
};
public static String div(String left, String right){
return normalize(unpack(left).replace(unpack(right),"I"));
}
public static String times(String left, String right){
return normalize(unpack(left).replace("I",unpack(right)));
}
public static String subs(String left, String right){
return normalize(unpack(left).replaceFirst(unpack(right),""));
}
public static String add(String left, String right) {
return normalize(unpack(left) + unpack(right));
}
private static String normalize(String roman) {
return super_replace(roman, values.length-1, -1, -1, 1, 0);
}
private static String unpack(String roman) {
return super_replace(roman, 0, values.length, 1, 0, 1);
}
private static String super_replace(String roman, int from, int to,
int step, int w_source, int w_target) {
for (int i = from; i != to; i += step) {
String[] pair = values[i];
String source = pair[w_source];
String target = pair[w_target];
roman = roman.replace(source, target);
}
return roman;
}
}
import static org.junit.Assert.*;
import org.junit.Test;
public class CalculatorTests {
@Test
public void onePlusOne(){
assertEquals("II",Calculator.add("I","I"));
}
@Test
public void onePlusTwo() {
assertEquals("III", Calculator.add("I","II"));
}
@Test
public void onePlusThree() {
assertEquals("IV", Calculator.add("I","III"));
}
@Test
public void threePlusOne() {
assertEquals("IV", Calculator.add("III","I"));
}
@Test
public void TwoPlusTwo() {
assertEquals("IV", Calculator.add("II","II"));
}
@Test
public void threePlusTwo() {
assertEquals("V", Calculator.add("III","II"));
}
@Test
public void FivePlusFive() {
assertEquals("X", Calculator.add("V","V"));
}
@Test
public void FivePlusFour() {
assertEquals("IX", Calculator.add("V","IV"));
}
@Test
public void TenPlusTwo() {
assertEquals("XII", Calculator.add("X","II"));
}
@Test
public void TenPlusFour() {
assertEquals("XIV", Calculator.add("X","IV"));
}
@Test
public void TenPlusNine() {
assertEquals("XIX", Calculator.add("X","IX"));
}
@Test
public void TenPlusNineReverse() {
assertEquals("XIX", Calculator.add("IX","X"));
}
@Test
public void fortyPlusFiftyThree() {
assertEquals("XCIII", Calculator.add("XL","LIII"));
}
@Test
public void fortyPlusFiftyThreeReverse() {
assertEquals("XCIII", Calculator.add("LIII","XL"));
}
@Test
public void add999() {
assertEquals("MCMXCVIII", Calculator.add("CMXCIX","CMXCIX"));
}
@Test
public void add19() {
assertEquals("XXXVIII", Calculator.add("XIX","XIX"));
}
@Test
public void add_to_999() {
assertEquals("CMXCIX", Calculator.add("CMXCVIII","I"));
}
@Test
public void add_to_600() {
assertEquals("DC", Calculator.add("CCC","CCC"));
}
@Test
public void add_to_15() {
assertEquals("XV", Calculator.add("VII","VIII"));
}
@Test
public void TwoLessOne() {
assertEquals("I", Calculator.subs("II", "I"));
}
@Test
public void times_to_56() {
assertEquals("LVI", Calculator.times("VII", "VIII"));
}
@Test
public void divide_56() {
assertEquals("VIII", Calculator.div("LVI", "VII"));
}
}
public class Calculator {
public static String add(String left, String right) {
return normalize( unpack(left) + unpack(right) );
}
private static String normalize(String roman) {
return roman
.replace("IIIII","V")
.replace("IIII","IV")
.replace("VV","X")
.replace("VIV","IX")
.replace("XXXXX", "L")
.replace("XXXX","XL")
.replace("LL","C")
.replace("LXL","XC")
.replace("CCCCC","D")
.replace("CCCC","CD")
.replace("DD","M")
.replace("DCD","CM")
;
}
private static String unpack(String roman) {
return roman
.replace("CM","DCD")
.replace("M","DD")
.replace("CD","CCCC")
.replace("D","CCCCC")
.replace("XC","LXL")
.replace("C","LL")
.replace("XL","XXXX")
.replace("L","XXXXX")
.replace("IX","VIV")
.replace("X","VV")
.replace("IV","IIII")
.replace("V","IIIII")
;
}
}