Adds an integer to roman converter utility
All checks were successful
KnarCraft/KnarLib/pipeline/head This commit looks good
All checks were successful
KnarCraft/KnarLib/pipeline/head This commit looks good
This commit is contained in:
@@ -0,0 +1,74 @@
|
|||||||
|
package net.knarcraft.knarlib.util;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility for converting from an integer to a roman numeral
|
||||||
|
*/
|
||||||
|
public final class IntegerToRomanUtil {
|
||||||
|
|
||||||
|
private final static List<Integer> romanValues = List.of(1000, 500, 100, 50, 10, 5, 1);
|
||||||
|
private final static List<Character> romanCharacters = List.of('M', 'D', 'C', 'L', 'X', 'V', 'I');
|
||||||
|
|
||||||
|
private IntegerToRomanUtil() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the given number as a roman number string
|
||||||
|
*
|
||||||
|
* @param number <p>The number to convert</p>
|
||||||
|
* @return <p>The roman representation of the number</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static String getRomanNumber(int number) {
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
int remainder = number;
|
||||||
|
for (int i = 0; i < romanCharacters.size(); i++) {
|
||||||
|
int romanValue = romanValues.get(i);
|
||||||
|
char romanCharacter = romanCharacters.get(i);
|
||||||
|
|
||||||
|
// Repeat the roman character, and calculate the new remainder
|
||||||
|
if (remainder >= romanValue) {
|
||||||
|
output.append(repeat(romanCharacter, remainder / romanValue));
|
||||||
|
remainder = remainder % romanValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit early to prevent unexpected trailing characters
|
||||||
|
if (remainder == 0) {
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the special case IV and similar
|
||||||
|
for (int j = i; j < romanCharacters.size(); j++) {
|
||||||
|
int value = romanValues.get(j);
|
||||||
|
int difference = Math.max(romanValue - value, 0);
|
||||||
|
|
||||||
|
/* If the remainder is "one" less than the current roman value, we hit the IV/IX/XL case.
|
||||||
|
Note that 5 triggers the special case when 10 is tested, as 5 = 10 - 5, which requires a test, so it
|
||||||
|
can be filtered out. */
|
||||||
|
if (remainder == difference && value != romanValue / 2) {
|
||||||
|
output.append(romanCharacters.get(j)).append(romanCharacter);
|
||||||
|
remainder = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Repeats the given character
|
||||||
|
*
|
||||||
|
* @param character <p>The character to repeat</p>
|
||||||
|
* @param times <p>The number of times to repeat the character</p>
|
||||||
|
* @return <p>The repeated string</p>
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
private static String repeat(char character, int times) {
|
||||||
|
return String.valueOf(character).repeat(Math.max(0, times));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,44 @@
|
|||||||
|
package net.knarcraft.knarlib.util;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static net.knarcraft.knarlib.util.IntegerToRomanUtil.getRomanNumber;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test class for IntegerToRomanConverter
|
||||||
|
*/
|
||||||
|
public class IntegerToRomanUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void basicNumbersTest() {
|
||||||
|
assertEquals("I", getRomanNumber(1));
|
||||||
|
assertEquals("II", getRomanNumber(2));
|
||||||
|
assertEquals("III", getRomanNumber(3));
|
||||||
|
assertEquals("IV", getRomanNumber(4));
|
||||||
|
assertEquals("V", getRomanNumber(5));
|
||||||
|
assertEquals("X", getRomanNumber(10));
|
||||||
|
assertEquals("XI", getRomanNumber(11));
|
||||||
|
assertEquals("XII", getRomanNumber(12));
|
||||||
|
assertEquals("XIII", getRomanNumber(13));
|
||||||
|
assertEquals("XIV", getRomanNumber(14));
|
||||||
|
assertEquals("XV", getRomanNumber(15));
|
||||||
|
assertEquals("XX", getRomanNumber(20));
|
||||||
|
assertEquals("L", getRomanNumber(50));
|
||||||
|
assertEquals("C", getRomanNumber(100));
|
||||||
|
assertEquals("D", getRomanNumber(500));
|
||||||
|
assertEquals("M", getRomanNumber(1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nineFourTest() {
|
||||||
|
assertEquals("IV", getRomanNumber(4));
|
||||||
|
assertEquals("IX", getRomanNumber(9));
|
||||||
|
assertEquals("XIV", getRomanNumber(14));
|
||||||
|
assertEquals("XIX", getRomanNumber(19));
|
||||||
|
assertEquals("XXIV", getRomanNumber(24));
|
||||||
|
assertEquals("XL", getRomanNumber(40));
|
||||||
|
assertEquals("IL", getRomanNumber(49));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user