1
0
Fork 0

day(25): sprinkle in some traits

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2023-01-07 17:00:25 +01:00
parent 38a2440438
commit f151a9a785
Signed by: mfocko
GPG key ID: 7C47D46246790496

View file

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