diff --git a/samples/day03.txt b/samples/day03.txt new file mode 100644 index 0000000..f17e726 --- /dev/null +++ b/samples/day03.txt @@ -0,0 +1,6 @@ +vJrwpWtwJgWrhcsFMMfFFhFp +jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL +PmmdzqPrVvPwwTWBwg +wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn +ttgJtRGJQctTZtZT +CrZsJsPPZsGzwwsLwLmpwMDw diff --git a/src/bin/day03.rs b/src/bin/day03.rs new file mode 100644 index 0000000..ed511db --- /dev/null +++ b/src/bin/day03.rs @@ -0,0 +1,95 @@ +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); + } +}