use std::{collections::HashMap, iter::zip, path::Path}; use crate::{error::AdventError, input::get_lines}; use super::*; pub struct Day1Part1 { list1: Vec, list2: Vec, } pub struct Day1Part2 { count1: HashMap, count2: HashMap } pub struct Day1 { part1: Day1Part1, part2: Day1Part2 } impl Day1 { pub fn new() -> Self { Day1 { part1: Day1Part1::new(), part2: Day1Part2::new() } } } impl AdventDay for Day1 { fn puzzle1(&mut self) -> Result { self.part1.read_input()?; self.part1.solve() } fn puzzle2(&mut self) -> Result { self.part2.read_input()?; self.part2.solve() } } impl Day1Part2 { fn new() -> Self { Day1Part2 { count1: HashMap::new(), count2: HashMap::new() } } } impl AdventDayPart2 for Day1Part2 { fn read_input(&mut self) -> Result<(),AdventError> { for line in get_lines(Path::new("resources/input1.txt")) { let line = line?; let mut s = line.split_whitespace(); let l = s.next().unwrap().parse::()?; if self.count1.contains_key(&l) { *self.count1.get_mut(&l).unwrap() += 1; } else { self.count1.insert(l, 1); } let r = s.next().unwrap().parse::()?; if self.count2.contains_key(&r) { *self.count2.get_mut(&r).unwrap() += 1; } else { self.count2.insert(r, 1); } } Ok(()) } fn solve(&mut self) -> Result { Ok(self.count1.keys().into_iter().map( |k| { let s = *k as u64; if self.count2.contains_key(k) { s * self.count1[k] * self.count2[k] } else { 0 } }).sum()) } } impl Day1Part1 { fn new() -> Self { Day1Part1 { list1: vec![], list2: vec![], } } } impl AdventDayPart1 for Day1Part1 { fn read_input(&mut self) -> Result<(),AdventError> { for line in get_lines(Path::new("resources/input1.txt")) { let line = line?; let mut s = line.split_whitespace(); self.list1.push(s.next().unwrap().parse::()?); self.list2.push(s.next().unwrap().parse::()?); } Ok(()) } fn solve(&mut self) -> Result { self.list1.sort(); self.list2.sort(); Ok(zip(self.list1.clone(), self.list2.clone()) .map(|(l, r)| { (l - r).abs() as u64 }) .sum::()) } }