Files
VV-ISTIC-TP4/code/roman-numerals/src/main/java/fr/istic/vv/RomanNumeraUtils.java
2025-12-12 16:43:56 +01:00

155 lines
5.3 KiB
Java

package fr.istic.vv;
import java.util.HashMap;
import java.util.Map;
public class RomanNumeraUtils {
final static Map<Character, Integer> mapToNum = new HashMap<>();
static {
mapToNum.put('M', 1000);
mapToNum.put('D', 500);
mapToNum.put('C', 100);
mapToNum.put('L', 50);
mapToNum.put('X', 10);
mapToNum.put('V', 5);
mapToNum.put('I', 1);
}
public static boolean isValidRomanNumeral(String value) {
boolean isValid = true;
char lastChar = ' ';
int nbLastChar = 0;
int valMax = 1001;
for(int i = 0; i<value.length() && isValid; i++){
char val = value.charAt(i);
if(mapToNum.containsKey(val) && mapToNum.get(val)<valMax){
if(lastChar!=' '){
if(mapToNum.get(val)>mapToNum.get(lastChar)){
//seul I X C peuvent soustraire un symbole (ex : IX XC CM)
if(lastChar == 'I' || lastChar == 'X' || lastChar == 'C'){
valMax = mapToNum.get(lastChar)-1;
//si plus de 1 soustraction (ex IIX) ou que la soustraction est ni 1/10 ni 1/5 du chiffre le plus grand
if(nbLastChar>1 || !(mapToNum.get(val)/10==mapToNum.get(lastChar) || mapToNum.get(val)/5==mapToNum.get(lastChar))){
isValid = false;
}
}
else isValid = false;
}
}
switch (val){
case 'M':
case 'C':
case 'X':
case 'I':
if(lastChar==value.charAt(i)){
nbLastChar++;
if(nbLastChar>3) isValid = false;
}
else{
lastChar = value.charAt(i);
nbLastChar = 1;
}
break;
case 'D':
case 'L':
case 'V':
if(lastChar==value.charAt(i)){
nbLastChar++;
if(nbLastChar>1) isValid = false;
}
else{
lastChar = value.charAt(i);
nbLastChar = 1;
}
break;
default:
isValid = false;
}
}
else isValid = false;
}
return isValid;
}
public static int parseRomanNumeral(String numeral) {
if(isValidRomanNumeral(numeral)){
int res = 0;
char lastChar = ' ';
for(int i = 0; i<numeral.length(); i++){
char val = numeral.charAt(i);
int value = mapToNum.get(val);
// -
if(i+1<numeral.length() && mapToNum.get(numeral.charAt(i+1))>value){ //XIX
res += 0;
} // -
else if(lastChar!=' ' && value>mapToNum.get(lastChar)){ //IX
res += value-mapToNum.get(lastChar);
}
else{
res +=mapToNum.get(val);
}
lastChar = val;
}
return res;
}
else throw new IllegalArgumentException("Invalid date");
}
public static String toRomanNumeral(int number) {
System.out.println(number);
String res = "";
char[] order = {'M','D','C','L','X','V','I'};
char[] sub = {'I','X','C'};
if(number<4000){
while(number>0){
boolean notFound = true;
for(int i = 0; i<order.length&&notFound; i++){
char symb = order[i];
int val = mapToNum.get(symb);
if(number>=val){
number -= val;
res = res + symb;
System.out.println(res);
notFound = false;
}
else{
boolean notFoundSub = true;
for(int j = 0; j<sub.length&&notFoundSub; j++){
char symbSub = sub[j];
int valSub = mapToNum.get(symbSub);
if(valSub*5==val || valSub*10==val){
if(number>=val-valSub){
number -= val-valSub;
res = res + symbSub + symb;
System.out.println(res);
notFoundSub = false;
notFound = false;
}
}
}
}
}
}
System.out.println("Return : " + res);
return res;
}
else throw new IllegalArgumentException("max 4000");
}
}