From b1d194cdb57712ae3c620d1519e3b674ce17dd1e Mon Sep 17 00:00:00 2001 From: Eric Martin Date: Thu, 28 Jun 2018 22:59:08 -0500 Subject: [PATCH] BAEL-1815: RomanNumeral and RomanArabicConverter (#4565) * BAEL-1815: RomanNumeral and RomanArabicConverter * Refactored getReverseSortedValues --- .../romannumerals/RomanArabicConverter.java | 52 +++++++++++++++++++ .../romannumerals/RomanNumeral.java | 26 ++++++++++ .../RomanArabicConverterUnitTest.java | 29 +++++++++++ 3 files changed, 107 insertions(+) create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java create mode 100644 algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java create mode 100644 algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java diff --git a/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java new file mode 100644 index 0000000000..ab0922ecf4 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanArabicConverter.java @@ -0,0 +1,52 @@ +package com.baeldung.algorithms.romannumerals; + +import java.util.List; + +class RomanArabicConverter { + + public static int romanToArabic(String input) { + String romanNumeral = input.toUpperCase(); + int result = 0; + + List romanNumerals = RomanNumeral.getReverseSortedValues(); + + int i = 0; + + while ((romanNumeral.length() > 0) && (i < romanNumerals.size())) { + RomanNumeral symbol = romanNumerals.get(i); + if (romanNumeral.startsWith(symbol.name())) { + result += symbol.getValue(); + romanNumeral = romanNumeral.substring(symbol.name().length()); + } else { + i++; + } + } + if (romanNumeral.length() > 0) { + throw new IllegalArgumentException(input + " cannot be converted to a Roman Numeral"); + } + + return result; + } + + public static String arabicToRoman(int number) { + if ((number <= 0) || (number > 4000)) { + throw new IllegalArgumentException(number + " is not in range (0,4000]"); + } + + List romanNumerals = RomanNumeral.getReverseSortedValues(); + + int i = 0; + StringBuilder sb = new StringBuilder(); + + while (number > 0 && i < romanNumerals.size()) { + RomanNumeral currentSymbol = romanNumerals.get(i); + if (currentSymbol.getValue() <= number) { + sb.append(currentSymbol.name()); + number -= currentSymbol.getValue(); + } else { + i++; + } + } + return sb.toString(); + } +} diff --git a/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java new file mode 100644 index 0000000000..219f0b5090 --- /dev/null +++ b/algorithms/src/main/java/com/baeldung/algorithms/romannumerals/RomanNumeral.java @@ -0,0 +1,26 @@ +package com.baeldung.algorithms.romannumerals; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +enum RomanNumeral { + I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000); + + private int value; + + RomanNumeral(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public static List getReverseSortedValues() { + return Arrays.stream(values()) + .sorted(Comparator.comparing((RomanNumeral e) -> e.value).reversed()) + .collect(Collectors.toList()); + } +} diff --git a/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java b/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java new file mode 100644 index 0000000000..b289ec6bc9 --- /dev/null +++ b/algorithms/src/test/java/com/baeldung/algorithms/romannumerals/RomanArabicConverterUnitTest.java @@ -0,0 +1,29 @@ +package com.baeldung.algorithms.romannumerals; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +public class RomanArabicConverterUnitTest { + + @Test + public void given2018Roman_WhenConvertingToArabic_ThenReturn2018() { + + String roman2018 = "MMXVIII"; + + int result = RomanArabicConverter.romanToArabic(roman2018); + + assertThat(result).isEqualTo(2018); + } + + @Test + public void given1999Arabic_WhenConvertingToRoman_ThenReturnMCMXCIX() { + + int arabic1999 = 1999; + + String result = RomanArabicConverter.arabicToRoman(arabic1999); + + assertThat(result).isEqualTo("MCMXCIX"); + } + +}