1
0
Fork 0
2022/src/bin/day03.rs
2023-01-06 20:00:52 +01:00

82 lines
1.9 KiB
Rust

use std::collections::HashSet;
use std::str::FromStr;
use aoc_2022::*;
type Input = Vec<Backpack>;
type Output = i32;
struct Backpack(HashSet<i32>, HashSet<i32>);
impl FromStr for Backpack {
type Err = Report;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut left: HashSet<i32> = HashSet::new();
let mut right: HashSet<i32> = HashSet::new();
let mid = s.len() / 2;
for (i, c) in s.chars().enumerate() {
let s = if i < mid { &mut left } else { &mut right };
s.insert(
c as i32
+ if c.is_ascii_lowercase() {
1 - 'a' as i32
} else {
27 - 'A' as i32
},
);
}
Ok(Backpack(left, right))
}
}
impl Backpack {
fn common_items(&self) -> HashSet<i32> {
let Backpack(left, right) = self;
left.intersection(right).cloned().collect()
}
fn all_items(&self) -> HashSet<i32> {
let Backpack(left, right) = self;
left.union(right).cloned().collect()
}
}
fn common_items(backpacks: &[Backpack]) -> HashSet<i32> {
backpacks
.iter()
.skip(1)
.fold(backpacks[0].all_items(), |u, b| {
u.intersection(&b.all_items()).cloned().collect()
})
}
struct Day03;
impl Solution<Input, Output> for Day03 {
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
file_to_structs(pathname)
}
fn part_1(input: &Input) -> Output {
input
.iter()
.map(|b| b.common_items().iter().sum::<i32>())
.sum()
}
fn part_2(input: &Input) -> Output {
input
.chunks(3)
.map(|backpacks| common_items(backpacks).iter().sum::<i32>())
.sum()
}
}
fn main() -> Result<()> {
Day03::main()
}
test_sample!(day_03, Day03, 157, 70);