diff --git a/data/examples/01.txt b/data/examples/01.txt new file mode 100644 index 000000000..b8af9ad --- /dev/null +++ b/data/examples/01.txt @@ -0,0 +1,6 @@ +3 4 +4 3 +2 5 +1 3 +3 9 +3 3 diff --git a/src/bin/01.rs b/src/bin/01.rs new file mode 100644 index 000000000..8dffccb --- /dev/null +++ b/src/bin/01.rs @@ -0,0 +1,57 @@ +use hashbrown::HashMap; +use itertools::Itertools; + +fn parse_input(input: &str) -> impl Iterator + '_ { + input.lines().map(|l| { + l.split(' ') + .filter_map(|x| x.parse::().ok()) + .collect_tuple() + .unwrap() + }) +} + +pub fn part_one(input: &str) -> Option { + let mut left = vec![]; + let mut right = vec![]; + + for (a, b) in parse_input(input) { + left.push(a); + right.push(b); + } + + left.sort(); + right.sort(); + + Some( + left.into_iter() + .zip(right) + .map(|(x, y)| (x - y).abs()) + .sum(), + ) +} + +pub fn part_two(input: &str) -> Option { + let mut map = HashMap::new(); + + for (a, b) in parse_input(input) { + map.entry(a).or_insert((0, 0)).0 += 1; + map.entry(b).or_insert((0, 0)).1 += 1; + } + + Some(map.into_iter().map(|(k, v)| k * v.0 * v.1).sum()) +} + +aoc::solution!(1); + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + assert_eq!(part_one(&aoc::template::read_file("examples", 1)), Some(11)); + } + #[test] + fn test_part_two() { + assert_eq!(part_two(&aoc::template::read_file("examples", 1)), Some(31)); + } +}