use std::collections::HashSet; use aoc_2022::*; use color_eyre::eyre::Result; use tracing::*; use tracing_subscriber::EnvFilter; type Input = Vec<(HashSet, HashSet)>; type Output = i32; fn part_1(input: &Input) -> Output { input .iter() .map(|(left, right)| left.intersection(right).sum::()) .sum() } fn part_2(input: &Input) -> Output { input .iter() .map(|(left, right)| left.union(right).cloned().collect()) .collect::>>() .chunks(3) .map(|sets| { // debug!("Sets: {:?}", sets); sets.iter() .skip(1) .fold(sets[0].clone(), |acc, s| { acc.intersection(s).cloned().collect() }) .iter() .fold(0, |acc, x| acc + *x) }) .sum() } fn parse_input(pathname: &str) -> Input { file_to_lines(pathname) .iter() .map(|line| { let mut left: HashSet = HashSet::new(); let mut right: HashSet = HashSet::new(); let mid = line.len() / 2; for (i, c) in line.chars().enumerate() { let s = if i < mid { &mut left } else { &mut right }; s.insert(if c < 'a' { c as i32 - 'A' as i32 + 27 } else { c as i32 - 'a' as i32 + 1 }); } (left, right) }) .collect() } fn main() -> Result<()> { tracing_subscriber::fmt() .with_env_filter(EnvFilter::from_default_env()) .with_target(false) .with_file(true) .with_line_number(true) .without_time() .compact() .init(); color_eyre::install()?; let input = parse_input("inputs/day03.txt"); info!("Part 1: {}", part_1(&input)); info!("Part 2: {}", part_2(&input)); Ok(()) } #[cfg(test)] mod tests { use super::*; #[test] fn test_part_1() { let sample = parse_input("samples/day03.txt"); assert_eq!(part_1(&sample), 157); } #[test] fn test_part_2() { let sample = parse_input("samples/day03.txt"); assert_eq!(part_2(&sample), 70); } }