That was a bitch to debug damn, but PE 089 finished now

This commit is contained in:
Philippe Zwietering
2023-03-30 09:23:37 +02:00
parent 091ef1f518
commit 49784eea22

View File

@@ -20,7 +20,23 @@ enum RomanNum {
use RomanNum::*; use RomanNum::*;
type RomanNumeral = Vec<RomanNum>; type RomanNumeral = Vec<RomanNum>;
impl RomanNum {
fn to_digit(&self) -> u32 {
match self {
I => 1,
V => 5,
X => 10,
L => 50,
C => 100,
D => 500,
M => 1000,
Empty => 0,
}
}
}
// This function is not correct at all but I'm not gonna bother fixing it // This function is not correct at all but I'm not gonna bother fixing it
#[deprecated]
fn _is_minimal(number: &RomanNumeral) -> bool { fn _is_minimal(number: &RomanNumeral) -> bool {
let mut last_num = Empty; let mut last_num = Empty;
let mut occ = 0; let mut occ = 0;
@@ -43,7 +59,8 @@ fn _is_minimal(number: &RomanNumeral) -> bool {
true true
} }
fn reduce(original: &RomanNumeral) -> RomanNumeral { #[deprecated]
fn _reduce(original: &RomanNumeral) -> RomanNumeral {
let mut last_num = Empty; let mut last_num = Empty;
let mut occ = 0; let mut occ = 0;
let mut result = vec![]; let mut result = vec![];
@@ -167,7 +184,8 @@ fn reduce(original: &RomanNumeral) -> RomanNumeral {
result result
} }
fn reduce_extra(numeral: &RomanNumeral) -> RomanNumeral { #[deprecated]
fn _reduce_extra(numeral: &RomanNumeral) -> RomanNumeral {
if numeral.len() <= 3 { if numeral.len() <= 3 {
return numeral.clone(); return numeral.clone();
} }
@@ -211,6 +229,106 @@ fn reduce_extra(numeral: &RomanNumeral) -> RomanNumeral {
result.into_iter().filter(|&n| n != Empty).collect() result.into_iter().filter(|&n| n != Empty).collect()
} }
fn roman_to_decimal(number: &RomanNumeral) -> u32 {
let mut result: i32 = 0;
let mut last;
let mut current = Empty;
for &num in number.iter() {
last = current;
current = num;
if last.to_digit() < current.to_digit() {
result -= last.to_digit() as i32;
} else {
result += last.to_digit() as i32;
}
}
result += current.to_digit() as i32;
result as u32
}
fn decimal_to_roman(number: u32) -> RomanNumeral {
let mut n = number;
let mut result = vec![];
while n > 0 {
while n >= 1000 {
result.push(M);
n -= 1000;
}
if n >= 900 {
result.push(C);
result.push(M);
n -= 900;
}
if n >= 500 {
result.push(D);
n -= 500;
}
if n >= 400 {
result.push(C);
result.push(D);
n -= 400;
}
while n >= 100 {
result.push(C);
n -= 100;
}
if n >= 90 {
result.push(X);
result.push(C);
n -= 90;
}
if n >= 50 {
result.push(L);
n -= 50;
}
if n >= 40 {
result.push(X);
result.push(L);
n -= 40;
}
while n >= 10 {
result.push(X);
n -= 10;
}
if n == 9 {
result.push(I);
result.push(X);
n -= 9;
}
if n >= 5 {
result.push(V);
n -= 5;
}
if n == 4 {
result.push(I);
result.push(V);
n -= 4;
}
while n > 0 {
result.push(I);
n -= 1;
}
}
result
}
fn parse_input(input: &str) -> IResult<&str, Vec<RomanNumeral>> { fn parse_input(input: &str) -> IResult<&str, Vec<RomanNumeral>> {
let (input, result) = separated_list1( let (input, result) = separated_list1(
multispace1, multispace1,
@@ -250,21 +368,37 @@ fn main() {
// println!("{:?}", res); // println!("{:?}", res);
let (_, numerals) = parse_input(input_text).unwrap(); let (_, numerals) = parse_input(input_text).unwrap();
let mut result = 0; let mut result = 0;
for mut numeral in numerals {
let start = numeral.len(); // for mut numeral in numerals {
let mut s = start; // let start = numeral.len();
loop { // let mut s = start;
numeral = reduce(&numeral); // loop {
numeral = reduce_extra(&numeral); // numeral = reduce(&numeral);
if s == numeral.len() { // numeral = reduce_extra(&numeral);
break; // if s == numeral.len() {
} // break;
s = numeral.len(); // }
} // s = numeral.len();
result += start - numeral.len(); // }
println!("{:?} , {}", numeral, start - numeral.len()); // result += start - numeral.len();
// println!("{:?} , {}", numeral, start - numeral.len());
// }
// Thanks chat gpt for giving me the direction of a solution that should work (although let the record state that the specific solution it generated was not correct at all)
for numeral in numerals {
let l = numeral.len();
let dec_version = roman_to_decimal(&numeral);
let rom_version = decimal_to_roman(dec_version);
// println!(
// "{:?} calculated to be {} then represented as {:?}",
// numeral, &dec_version, &rom_version,
// );
debug_assert!(l >= rom_version.len());
result += l - rom_version.len();
} }
println!("The number of characters that can be saved is: {}", result); println!("The number of characters that can be saved is: {}", result);