Exo 1 en cours

This commit is contained in:
trochas
2025-12-12 16:43:56 +01:00
parent 3614fabca5
commit bf02648bb3
4 changed files with 261 additions and 6 deletions

View File

@@ -1,11 +1,154 @@
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");
public static boolean isValidRomanNumeral(String value) { return false; }
public static int parseRomanNumeral(String numeral) { return 0; }
public static String toRomanNumeral(int number) { return ""; }
}
}

View File

@@ -1,8 +1,120 @@
package fr.istic.vv;
import net.jqwik.api.*;
import net.jqwik.api.constraints.IntRange;
import static fr.istic.vv.RomanNumeraUtils.*;
public class RomanNumeralTest {
@Example
void simpleValidRomanNumerals() {
assert isValidRomanNumeral("I");
assert isValidRomanNumeral("II");
assert isValidRomanNumeral("III");
assert isValidRomanNumeral("IV");
assert isValidRomanNumeral("VI");
assert isValidRomanNumeral("VIII");
assert isValidRomanNumeral("IX");
assert isValidRomanNumeral("X");
assert isValidRomanNumeral("XI");
assert isValidRomanNumeral("MI");
assert isValidRomanNumeral("XIII");
}
@Example
void nonValidRomanNumeralsBadLetter() {
assert !isValidRomanNumeral("IIIA");
assert !isValidRomanNumeral("A");
assert !isValidRomanNumeral("CAI");
}
@Example
void nonValidRomanNumeralsRepeated() {
assert !isValidRomanNumeral("IIII");
assert !isValidRomanNumeral("XXXX");
assert !isValidRomanNumeral("CCCC");
assert !isValidRomanNumeral("MMMM");
assert !isValidRomanNumeral("DD");
assert !isValidRomanNumeral("LL");
assert !isValidRomanNumeral("VV");
}
@Example
void validRomanNumeralsLeftSub() {
assert isValidRomanNumeral("IV");
assert isValidRomanNumeral("IX");
assert isValidRomanNumeral("XL");
assert isValidRomanNumeral("XC");
assert isValidRomanNumeral("CD");
assert isValidRomanNumeral("CM");
}
@Example
void nonValidRomanNumeralsLeftSub() {
assert !isValidRomanNumeral("VX");
assert !isValidRomanNumeral("VL");
assert !isValidRomanNumeral("IL");
assert !isValidRomanNumeral("IC");
assert !isValidRomanNumeral("VC");
assert !isValidRomanNumeral("LC");
assert !isValidRomanNumeral("ID");
assert !isValidRomanNumeral("VD");
assert !isValidRomanNumeral("XD");
assert !isValidRomanNumeral("LD");
assert !isValidRomanNumeral("IM");
assert !isValidRomanNumeral("VM");
assert !isValidRomanNumeral("XM");
assert !isValidRomanNumeral("LM");
assert !isValidRomanNumeral("DM");
}
@Example
void completValidRomanNumerals() {
assert isValidRomanNumeral("MCDXXXIV");
assert isValidRomanNumeral("DCCLXXXIX");
assert isValidRomanNumeral("LXIX");
assert isValidRomanNumeral("MCCXXXIV");
}
@Example
void completNonValidRomanNumerals() {
assert !isValidRomanNumeral("IXX");
assert !isValidRomanNumeral("IXIXIX");
assert !isValidRomanNumeral("MMMDCCCLIXXXVIII");
assert !isValidRomanNumeral("XIXV");
}
@Example
void testParseRomanNumeral() {
assert parseRomanNumeral("XX")==20;
assert parseRomanNumeral("XIX")==19;
assert parseRomanNumeral("XXI")==21;
assert parseRomanNumeral("IX")==9;
assert parseRomanNumeral("MCCXXXIV")==1234;
}
@Example
void testToRomanNumeral() {
assert toRomanNumeral(20).compareTo("XX")==0;
assert toRomanNumeral(19).compareTo("XIX")==0;
assert toRomanNumeral(21).compareTo("XXI")==0;
assert toRomanNumeral(9).compareTo("IX")==0;
assert toRomanNumeral(1234).compareTo("MCCXXXIV")==0;
assert toRomanNumeral(3999).compareTo("MMMCMXCIX")==0;
}
@Property
boolean absoluteValueOfAllNumbersIsPositive(@ForAll @IntRange(min=Integer.MIN_VALUE +1) int anInteger) {
return Math.abs(anInteger) >= 0;