From 45d09b301cd0f34b375f9d25803f4d25da716c20 Mon Sep 17 00:00:00 2001 From: Nelson-Lemercier Date: Mon, 15 Oct 2018 15:41:43 +0300 Subject: [PATCH] Assignment finished --- src/RomanNumerals.java | 233 ++++++++++++++++++++++++++- src/RomanNumeralsException.java | 10 ++ tests/TestRomanNumerals.java | 274 +++++++++++++++++++++++++++++++- 3 files changed, 511 insertions(+), 6 deletions(-) create mode 100644 src/RomanNumeralsException.java diff --git a/src/RomanNumerals.java b/src/RomanNumerals.java index 20904f0..fb6cece 100644 --- a/src/RomanNumerals.java +++ b/src/RomanNumerals.java @@ -1,8 +1,233 @@ - public class RomanNumerals { - public int convertToInteger(String romanNum) { - // To be Implemented - return 0; + + public int convertToInteger(String romanNum) throws RomanNumeralsException { + + int sum = 0; + + if(checkInput(romanNum)) { + + if(check_IXCM_3_times(romanNum)) { + + if(check_VLD_Once(romanNum)) { + + if(check_substraction_rule(romanNum)) { + + if(check_one_substraction(romanNum)) { + + for(int i = romanNum.length() - 1; i >= 0; i--) { + + if(i != 0 && letterValue(romanNum.charAt(i)) > letterValue(romanNum.charAt(i - 1))) { + + sum = sum + letterValue(romanNum.charAt(i)) - 2 * letterValue(romanNum.charAt(i - 1)); + + } + + else { + + sum += letterValue(romanNum.charAt(i)); + + } + + } + + } + + } + + } + + } + + } + + return sum; + + } + + public int letterValue(char letter) throws RomanNumeralsException { + + int value = -1; + + switch(letter) { + + case 'I': + + value = 1; + break; + + case 'V': + + value = 5; + break; + + case 'X': + + value = 10; + break; + + case 'L': + + value = 50; + break; + + case 'C': + + value = 100; + break; + + case 'D': + + value = 500; + break; + + case 'M': + + value = 1000; + break; + + default: + + throw new RomanNumeralsException(); + + + } + + return value; + + } + + public boolean checkInput(String RomanNum) throws RomanNumeralsException { + + for(int i = 0; i < RomanNum.length(); i++) { + + letterValue(RomanNum.charAt(i)); + + } + + return true; + + } + + public boolean check_IXCM_3_times(String RomanNum) throws RomanNumeralsException { + + char previousLetter = ' '; + int count = 0; + + for(int i = 0; i < RomanNum.length(); i++) { + + if(RomanNum.charAt(i) == 'I' || RomanNum.charAt(i) == 'X' || RomanNum.charAt(i) == 'C' || RomanNum.charAt(i) == 'M') { + + if(RomanNum.charAt(i) == previousLetter) { + + count++; + + } + + else { + + count = 1; + + previousLetter = RomanNum.charAt(i); + + } + + } + + if(count > 3) { + + throw new RomanNumeralsException(); + + } + + } + + return true; + + + } + + public boolean check_VLD_Once(String RomanNum) throws RomanNumeralsException { + + char previousLetter = ' '; + int count = 0; + + for(int i = 0; i < RomanNum.length(); i++) { + + if(RomanNum.charAt(i) == 'V' || RomanNum.charAt(i) == 'L' || RomanNum.charAt(i) == 'D') { + + if(RomanNum.charAt(i) == previousLetter) { + + count++; + + } + + else { + + count = 1; + + previousLetter = RomanNum.charAt(i); + + } + + } + + if(count > 1) { + + throw new RomanNumeralsException(); + + } + + } + + return true; + + + } + + public boolean check_substraction_rule(String RomanNum) throws RomanNumeralsException { + + for(int i = 0; i < RomanNum.length() - 1; i++) { + + if(letterValue(RomanNum.charAt(i)) < letterValue(RomanNum.charAt(i + 1))) { + + if(letterValue(RomanNum.charAt(i)) > 10 * letterValue(RomanNum.charAt(i + 1))) { + + throw new RomanNumeralsException(); + + } + + if(RomanNum.charAt(i) == 'V' || RomanNum.charAt(i) == 'L' || RomanNum.charAt(i) == 'D') { + + throw new RomanNumeralsException(); + + } + + } + + } + + return true; + + } + + public boolean check_one_substraction(String RomanNum) throws RomanNumeralsException { + + for(int i = 0; i < RomanNum.length() - 2; i++) { + + if(letterValue(RomanNum.charAt(i)) == letterValue(RomanNum.charAt(i + 1))) { + + if(letterValue(RomanNum.charAt(i + 1)) < letterValue(RomanNum.charAt(i + 2))) { + + throw new RomanNumeralsException(); + + } + + } + + } + + return true; } + } diff --git a/src/RomanNumeralsException.java b/src/RomanNumeralsException.java new file mode 100644 index 0000000..4d268fc --- /dev/null +++ b/src/RomanNumeralsException.java @@ -0,0 +1,10 @@ + +public class RomanNumeralsException extends Exception{ + + public RomanNumeralsException() { + + System.out.println("Wrong format : correct roman number format required. Please check the rules."); + + } + +} diff --git a/tests/TestRomanNumerals.java b/tests/TestRomanNumerals.java index 5d1de75..6723884 100644 --- a/tests/TestRomanNumerals.java +++ b/tests/TestRomanNumerals.java @@ -2,11 +2,281 @@ import org.junit.Test; +import junit.framework.AssertionFailedError; + public class TestRomanNumerals { + + + //--------------------------------------------------- + //Simple tests : one letter @Test - public void test() { - fail("Not yet implemented"); + public void test_I() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(1, rn.letterValue('I')); + } + + @Test + public void test_V() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(5, rn.letterValue('V')); + } + + @Test + public void test_X() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(10, rn.letterValue('X')); + } + + @Test + public void test_L() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(50, rn.letterValue('L')); + } + + @Test + public void test_C() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(100, rn.letterValue('C')); + } + + @Test + public void test_D() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(500, rn.letterValue('D')); + } + + @Test + public void test_M() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(1000, rn.letterValue('M')); + } + + //--------------------------------------------------- + // The symbols 'I', 'X', 'C', and 'M' can be repeated at most 3 times in a row + + // I + + @Test + public void test_I_twice() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("II")); + } + + @Test + public void test_I_three_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("III")); + } + + @Test(expected = RomanNumeralsException.class) + public void test_I_four_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_IXCM_3_times("IIII"); + } + + //____________________________________ + + // X + + @Test + public void test_X_twice() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("XX")); + } + + @Test + public void test_X_three_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("XXX")); + } + + @Test(expected = RomanNumeralsException.class) + public void test_X_four_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_IXCM_3_times("XXXX"); + } + + //____________________________________ + + // C + + @Test + public void test_C_twice() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("CC")); + } + + @Test + public void test_C_three_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("CCC")); + } + + @Test(expected = RomanNumeralsException.class) + public void test_C_four_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_IXCM_3_times("CCCC"); + } + + //____________________________________ + + // M + + @Test + public void test_M_twice() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("MM")); + } + + @Test + public void test_M_three_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_IXCM_3_times("MMM")); + } + + @Test(expected = RomanNumeralsException.class) + public void test_M_four_times() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_IXCM_3_times("MMMM"); + } + + //--------------------------------------------------- + // The symbols 'V', 'L' and 'D' can never be repeated + + @Test(expected = RomanNumeralsException.class) + public void test_V_twice() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_VLD_Once("VV"); } + + @Test(expected = RomanNumeralsException.class) + public void test_L_twice() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_VLD_Once("LL"); + } + + @Test(expected = RomanNumeralsException.class) + public void test_D_twice() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_VLD_Once("DD"); + } + + //--------------------------------------------------- + // The '1' symbols ('I', 'X', and 'C') can only be subtracted from the next highest values ('IV' and 'IX', 'XL' and 'XC', 'CD' and 'CM') + @Test + public void test_IV() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_substraction_rule("IV")); + } + + @Test + public void test_IX() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_substraction_rule("IX")); + } + + @Test + public void test_XL() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_substraction_rule("XL")); + } + + @Test + public void test_XC() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_substraction_rule("XC")); + } + + @Test + public void test_CD() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_substraction_rule("CD")); + } + + @Test + public void test_CM() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_substraction_rule("CM")); + } + + //--------------------------------------------------- + // Only one subtraction can be made per numeral ('XC' is allowed, 'XXC' is not) + + @Test + public void test_1_substraction() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.check_one_substraction("XC")); + } + + @Test(expected = RomanNumeralsException.class) + public void test_2_substraction() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_one_substraction("XXC"); + } + + //--------------------------------------------------- + // The '5' symbols ('V', 'L' and 'D') can never be subtracted + + @Test(expected = RomanNumeralsException.class) + public void test_V_substraction() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_substraction_rule("VX"); + } + + @Test(expected = RomanNumeralsException.class) + public void test_L_substraction() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_substraction_rule("LC"); + } + + @Test(expected = RomanNumeralsException.class) + public void test_D_substraction() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.check_substraction_rule("DM"); + } + + //--------------------------------------------------- + // Test inputs + + @Test + public void test_correct_input() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(true, rn.checkInput("MCMLXXXIV")); + } + + @Test(expected = RomanNumeralsException.class) + public void test_wrong_input() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + rn.checkInput("X12XC"); + } + + //--------------------------------------------------- + // Test convertToInteger + + @Test + public void convertToInteger1() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(1984, rn.convertToInteger("MCMLXXXIV")); + } + + @Test + public void convertToInteger2() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(2014, rn.convertToInteger("MMXIV")); + } + + @Test + public void convertToInteger3() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(666, rn.convertToInteger("DCLXVI")); + } + + @Test + public void convertToInteger4() throws RomanNumeralsException { + RomanNumerals rn = new RomanNumerals(); + assertEquals(1515, rn.convertToInteger("MDXV")); + } + }