use std::collections::HashSet; use std::str::FromStr; use aoc_2022::*; type Input = Vec; type Output = i32; struct Backpack(HashSet, HashSet); impl FromStr for Backpack { type Err = Report; fn from_str(s: &str) -> Result { let mut left: HashSet = HashSet::new(); let mut right: HashSet = 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 { let Backpack(left, right) = self; left.intersection(right).cloned().collect() } fn all_items(&self) -> HashSet { let Backpack(left, right) = self; left.union(right).cloned().collect() } } fn common_items(backpacks: &[Backpack]) -> HashSet { backpacks .iter() .skip(1) .fold(backpacks[0].all_items(), |u, b| { u.intersection(&b.all_items()).cloned().collect() }) } struct Day03; impl Solution for Day03 { fn parse_input>(pathname: P) -> Input { file_to_structs(pathname) } fn part_1(input: &Input) -> Output { input .iter() .map(|b| b.common_items().iter().sum::()) .sum() } fn part_2(input: &Input) -> Output { input .chunks(3) .map(|backpacks| common_items(backpacks).iter().sum::()) .sum() } } fn main() -> Result<()> { Day03::main() } test_sample!(day_03, Day03, 157, 70);