day(25): sprinkle in some traits
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
38a2440438
commit
f151a9a785
1 changed files with 57 additions and 37 deletions
|
@ -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<String>;
|
||||
type Input = Vec<SpecialFuelUnits>;
|
||||
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<char> = 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<Self, Self::Err> {
|
||||
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<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 {
|
||||
-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<i64> for SpecialFuelUnits {
|
||||
fn from(value: i64) -> Self {
|
||||
Self { value }
|
||||
}
|
||||
}
|
||||
|
||||
struct Day25;
|
||||
impl Solution<Input, Output> for Day25 {
|
||||
fn parse_input<P: AsRef<Path>>(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::<i64>()).to_string()
|
||||
}
|
||||
|
||||
fn part_2(_input: &Input) -> Output {
|
||||
|
@ -71,7 +91,7 @@ test_sample!(
|
|||
);
|
||||
|
||||
lazy_static! {
|
||||
static ref EXAMPLES: HashMap<isize, &'static str> = HashMap::from([
|
||||
static ref EXAMPLES: HashMap<i64, &'static str> = 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::<SpecialFuelUnits>().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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue