pub fn pt1(input: &str) -> usize { let elems = input .lines() .filter_map(|l| l.split_once(" ")) .map(|(l, r)| (l.parse::(), r.parse::())) .filter(|(l, r)| l.is_ok() && r.is_ok()) .map(|(l, r)| (l.unwrap(), r.unwrap())); let mut lefts = elems.clone().map(|(l, _)| l).collect::>(); let mut rights = elems.map(|(_, r)| r).collect::>(); lefts.sort_unstable(); rights.sort_unstable(); lefts .iter() .zip(rights.iter()) .map(|(l, r)| l.abs_diff(*r)) .sum() } pub fn pt2(input: &str) -> usize { let elems = input .lines() .filter_map(|l| l.split_once(" ")) .map(|(l, r)| (l.parse::(), r.parse::())) .filter(|(l, r)| l.is_ok() && r.is_ok()) .map(|(l, r)| (l.unwrap(), r.unwrap())); let lefts = elems.clone().map(|(l, _)| l); let rights = elems.map(|(_, r)| r).collect::>(); lefts .map(|l| rights.clone().iter().filter(|r| **r == l).count() * l) .sum() } #[cfg(test)] mod tests { use std::fs::read_to_string; use super::{pt1, pt2}; #[test] pub fn test_pt1() { let input = read_to_string("./inputs/day01/example.txt").expect("Missing example.txt for day01"); assert_eq!(pt1(&input), 11) } #[test] pub fn test_pt2() { let input = read_to_string("./inputs/day01/example.txt").expect("Missing example.txt for day01"); assert_eq!(pt2(&input), 31) } }