diff --git a/src/bin/day25.rs b/src/bin/day25.rs index 2a369ae..c0e5ac8 100644 --- a/src/bin/day25.rs +++ b/src/bin/day25.rs @@ -1,56 +1,76 @@ -use std::{char::from_digit, collections::HashMap}; +use std::{char::from_digit, collections::HashMap, fmt::Display, str::FromStr}; use aoc_2022::*; -type Input = Vec; +type Input = Vec; type Output = String; -fn from_snafu(s: &str) -> isize { - (0..) - .zip(s.chars().rev()) - .map(|(e, d)| { - 5_isize.pow(e) - * match d { - '-' => -1, - '=' => -2, - _ => d.to_digit(10).unwrap().try_into().unwrap(), - } - }) - .sum() +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +struct SpecialFuelUnits { + value: i64, } -fn to_snafu(mut n: isize) -> String { - let mut digits: Vec = Vec::new(); +impl FromStr for SpecialFuelUnits { + type Err = Report; - while n > 0 { - let mut d = n % 5; - if d > 2 { - n += 5 - d; - d -= 5; + fn from_str(s: &str) -> std::result::Result { + let value = (0..) + .zip(s.chars().rev()) + .map(|(e, d)| { + 5_i64.pow(e) + * match d { + '-' => -1, + '=' => -2, + _ => d.to_digit(10).unwrap().try_into().unwrap(), + } + }) + .sum(); + + Ok(Self { value }) + } +} + +impl Display for SpecialFuelUnits { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut n = self.value; + let mut digits: Vec = Vec::new(); + + while n > 0 { + let mut d = n % 5; + if d > 2 { + n += 5 - d; + d -= 5; + } + + digits.push(match d { + -1 => '-', + -2 => '=', + _ => from_digit(d as u32, 10).unwrap(), + }); + + n /= 5; } - digits.push(match d { - -1 => '-', - -2 => '=', - _ => from_digit(d as u32, 10).unwrap(), - }); + digits.reverse(); - n /= 5; + write!(f, "{}", digits.iter().join("")) } +} - digits.reverse(); - - digits.iter().join("") +impl From for SpecialFuelUnits { + fn from(value: i64) -> Self { + Self { value } + } } struct Day25; impl Solution for Day25 { fn parse_input>(pathname: P) -> Input { - file_to_lines(pathname) + file_to_structs(pathname) } fn part_1(input: &Input) -> Output { - to_snafu(input.iter().map(|s| from_snafu(s)).sum()) + SpecialFuelUnits::from(input.iter().map(|s| s.value).sum::()).to_string() } fn part_2(_input: &Input) -> Output { @@ -71,7 +91,7 @@ test_sample!( ); lazy_static! { - static ref EXAMPLES: HashMap = HashMap::from([ + static ref EXAMPLES: HashMap = HashMap::from([ (1, "1"), (2, "2"), (3, "1="), @@ -108,15 +128,15 @@ mod day_25_snafu { #[test] fn test_from() { - for (n, s) in EXAMPLES.iter() { - assert_eq!(from_snafu(s), *n); + for (&n, s) in EXAMPLES.iter() { + assert_eq!(s.parse::().unwrap().value, n); } } #[test] fn test_to() { - for (n, s) in EXAMPLES.iter() { - assert_eq!(to_snafu(*n), s.to_string()); + for (&n, s) in EXAMPLES.iter() { + assert_eq!(SpecialFuelUnits::from(n).to_string(), s.to_string()); } } }