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::*;
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue