robermorales
8/24/2013 - 12:14 AM

Solution to Kata "Roman Calculator" http://codingdojo.org/cgi-bin/wiki.pl?KataRomanCalculator @CarlosCondor @robermorales

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")
				;
	}

}