use std::collections::HashMap; fn main() { let input = std::fs::read_to_string("input").unwrap(); println!("{}", pt2(&input)); } fn pt1(input: &str) -> i32 { let (mut left, mut right) = parse_input(input); left.sort_unstable(); right.sort_unstable(); left.iter() .zip(right.iter()) .map(|(l, r)| (l - r).abs()) .sum() } fn pt2(input: &str) -> i32 { let (left, right) = parse_input(input); let mut rights = HashMap::new(); for num in &right { *rights.entry(num).or_insert(0) += 1; } left.iter().map(|n| n * rights.get(n).unwrap_or(&0)).sum() } fn parse_input(input: &str) -> (Vec, Vec) { let mut left = Vec::new(); let mut right = Vec::new(); for line in input.split("\n") { let line: Vec<&str> = line .split(|c: char| c.is_whitespace()) .filter(|c| !c.is_empty()) .collect(); if line.len() < 2 { continue; } let l: i32 = line[0].parse().unwrap(); let r: i32 = line[1].parse().unwrap(); left.push(l); right.push(r); } (left, right) } #[cfg(test)] mod test { use super::*; static P1_TEST: &str = "3 4 4 3 2 5 1 3 3 9 3 3 "; #[test] fn test_p1() { let val = pt1(P1_TEST); assert_eq!(11, val); } #[test] fn test_p2() { let val = pt2(P1_TEST); assert_eq!(31, val); } }