use std::{collections::HashMap, iter::zip}; pub fn process_part1(input: &str) -> i32 { let mut left = Vec::new(); let mut right = Vec::new(); input.lines().for_each(|line| { let (left_val, right_val) = line.split_once(" ").unwrap(); left.push(left_val.parse::().unwrap()); right.push(right_val.parse::().unwrap()); }); left.sort(); right.sort(); let mut res = 0; for (left_val, right_val) in zip(left, right) { res += (left_val - right_val).abs(); } res } pub fn process_part2(input: &str) -> i32 { let mut left = Vec::new(); let mut right = HashMap::new(); input.lines().for_each(|line| { let (left_val, right_val) = line.split_once(" ").unwrap(); left.push(left_val.parse::().unwrap()); right .entry(right_val.parse::().unwrap()) .and_modify(|value| *value += 1) .or_insert(1); }); left.sort(); let mut res = 0; for left_val in left { let right_val_count = right.get(&left_val).unwrap_or(&0); res += left_val * right_val_count; } res } #[cfg(test)] mod tests { use super::*; const INPUT: &str = "3 4 4 3 2 5 1 3 3 9 3 3"; #[test] fn part1() { let result = process_part1(INPUT); assert_eq!(result, 11); } #[test] fn part2() { let result = process_part2(INPUT); assert_eq!(result, 31); } }