Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 48 additions & 48 deletions src/main/java/com/thealgorithms/conversions/IntegerToRoman.java
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
package com.thealgorithms.conversions;

/**
* Converting Integers into Roman Numerals
* A utility class to convert integers into Roman numerals.
*
* <p>
* ('I', 1); ('IV',4); ('V', 5); ('IX',9); ('X', 10); ('XL',40); ('L', 50);
* ('XC',90); ('C', 100); ('D', 500); ('M', 1000);
* <p>Roman numerals follow these rules:
* <ul>
* <li>I = 1</li>
* <li>IV = 4</li>
* <li>V = 5</li>
* <li>IX = 9</li>
* <li>X = 10</li>
* <li>XL = 40</li>
* <li>L = 50</li>
* <li>XC = 90</li>
* <li>C = 100</li>
* <li>D = 500</li>
* <li>M = 1000</li>
* </ul>
*
* <p>Conversion is based on repeatedly subtracting the largest possible Roman numeral value
* from the input number until it reaches zero. For example, 1994 is converted as:
* <pre>
* 1994 -> MCMXCIV (1000 + 900 + 90 + 4)
* </pre>
*/
public final class IntegerToRoman {

// Array of Roman numeral values in descending order
private static final int[] ALL_ROMAN_NUMBERS_IN_ARABIC = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};

// Corresponding Roman numeral symbols
private static final String[] ALL_ROMAN_NUMBERS = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};

private IntegerToRoman() {
}

private static final int[] ALL_ROMAN_NUMBERS_IN_ARABIC = new int[] {
1000,
900,
500,
400,
100,
90,
50,
40,
10,
9,
5,
4,
1,
};
private static final String[] ALL_ROMAN_NUMBERS = new String[] {
"M",
"CM",
"D",
"CD",
"C",
"XC",
"L",
"XL",
"X",
"IX",
"V",
"IV",
"I",
};

// Value must be > 0
/**
* Converts an integer to its Roman numeral representation.
* Steps:
* <ol>
* <li>Iterate over the Roman numeral values in descending order</li>
* <li>Calculate how many times a numeral fits</li>
* <li>Append the corresponding symbol</li>
* <li>Subtract the value from the number</li>
* <li>Repeat until the number is zero</li>
* <li>Return the Roman numeral representation</li>
* </ol>
*
* @param num the integer value to convert (must be greater than 0)
* @return the Roman numeral representation of the input integer
* or an empty string if the input is non-positive
*/
public static String integerToRoman(int num) {
if (num <= 0) {
return "";
}

StringBuilder builder = new StringBuilder();

for (int a = 0; a < ALL_ROMAN_NUMBERS_IN_ARABIC.length; a++) {
int times = num / ALL_ROMAN_NUMBERS_IN_ARABIC[a];
for (int b = 0; b < times; b++) {
builder.append(ALL_ROMAN_NUMBERS[a]);
}

num -= times * ALL_ROMAN_NUMBERS_IN_ARABIC[a];
for (int i = 0; i < ALL_ROMAN_NUMBERS_IN_ARABIC.length; i++) {
int times = num / ALL_ROMAN_NUMBERS_IN_ARABIC[i];
builder.append(ALL_ROMAN_NUMBERS[i].repeat(Math.max(0, times)));
num -= times * ALL_ROMAN_NUMBERS_IN_ARABIC[i];
}

return builder.toString();
}

public static void main(String[] args) {
System.out.println(IntegerToRoman.integerToRoman(2131));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,30 @@ public class IntegerToRomanTest {
public void testIntegerToRoman() {
assertEquals("MCMXCIV", IntegerToRoman.integerToRoman(1994));
assertEquals("LVIII", IntegerToRoman.integerToRoman(58));
assertEquals("IV", IntegerToRoman.integerToRoman(4));
assertEquals("IX", IntegerToRoman.integerToRoman(9));
assertEquals("MMM", IntegerToRoman.integerToRoman(3000));
}

@Test
public void testSmallNumbers() {
assertEquals("I", IntegerToRoman.integerToRoman(1));
assertEquals("II", IntegerToRoman.integerToRoman(2));
assertEquals("III", IntegerToRoman.integerToRoman(3));
}

@Test
public void testRoundNumbers() {
assertEquals("X", IntegerToRoman.integerToRoman(10));
assertEquals("L", IntegerToRoman.integerToRoman(50));
assertEquals("C", IntegerToRoman.integerToRoman(100));
assertEquals("D", IntegerToRoman.integerToRoman(500));
assertEquals("M", IntegerToRoman.integerToRoman(1000));
}

@Test
public void testEdgeCases() {
assertEquals("", IntegerToRoman.integerToRoman(0)); // Non-positive number case
assertEquals("", IntegerToRoman.integerToRoman(-5)); // Negative number case
}
}