That was a bitch to debug damn, but PE 089 finished now
This commit is contained in:
@@ -20,7 +20,23 @@ enum RomanNum {
|
||||
use 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
|
||||
#[deprecated]
|
||||
fn _is_minimal(number: &RomanNumeral) -> bool {
|
||||
let mut last_num = Empty;
|
||||
let mut occ = 0;
|
||||
@@ -43,7 +59,8 @@ fn _is_minimal(number: &RomanNumeral) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn reduce(original: &RomanNumeral) -> RomanNumeral {
|
||||
#[deprecated]
|
||||
fn _reduce(original: &RomanNumeral) -> RomanNumeral {
|
||||
let mut last_num = Empty;
|
||||
let mut occ = 0;
|
||||
let mut result = vec![];
|
||||
@@ -167,7 +184,8 @@ fn reduce(original: &RomanNumeral) -> RomanNumeral {
|
||||
result
|
||||
}
|
||||
|
||||
fn reduce_extra(numeral: &RomanNumeral) -> RomanNumeral {
|
||||
#[deprecated]
|
||||
fn _reduce_extra(numeral: &RomanNumeral) -> RomanNumeral {
|
||||
if numeral.len() <= 3 {
|
||||
return numeral.clone();
|
||||
}
|
||||
@@ -211,6 +229,106 @@ fn reduce_extra(numeral: &RomanNumeral) -> RomanNumeral {
|
||||
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>> {
|
||||
let (input, result) = separated_list1(
|
||||
multispace1,
|
||||
@@ -250,21 +368,37 @@ fn main() {
|
||||
// println!("{:?}", res);
|
||||
|
||||
let (_, numerals) = parse_input(input_text).unwrap();
|
||||
|
||||
let mut result = 0;
|
||||
for mut numeral in numerals {
|
||||
let start = numeral.len();
|
||||
let mut s = start;
|
||||
loop {
|
||||
numeral = reduce(&numeral);
|
||||
numeral = reduce_extra(&numeral);
|
||||
if s == numeral.len() {
|
||||
break;
|
||||
}
|
||||
s = numeral.len();
|
||||
}
|
||||
result += start - numeral.len();
|
||||
println!("{:?} , {}", numeral, start - numeral.len());
|
||||
|
||||
// for mut numeral in numerals {
|
||||
// let start = numeral.len();
|
||||
// let mut s = start;
|
||||
// loop {
|
||||
// numeral = reduce(&numeral);
|
||||
// numeral = reduce_extra(&numeral);
|
||||
// if s == numeral.len() {
|
||||
// break;
|
||||
// }
|
||||
// s = 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);
|
||||
|
||||
Reference in New Issue
Block a user