diff --git a/src/day5.rs b/src/day5.rs new file mode 100644 index 0000000..680f7e0 --- /dev/null +++ b/src/day5.rs @@ -0,0 +1,47 @@ +use std::{cmp::Ordering, collections::HashMap}; + +pub fn day5() { + let full_input = crate::input(5); + let input_parts: Vec<&str> = full_input.split("\n\n").collect(); + let order_rules: Vec> = input_parts[0] + .lines() + .filter(|line| !line.is_empty()) + .map(|line| line.split("|").map(|x| x.parse::().unwrap()).collect()) + .collect(); + let page_sets: Vec> = input_parts[1] + .lines() + .filter(|line| !line.is_empty()) + .map(|line| line.split(",").map(|x| x.parse::().unwrap()).collect()) + .collect(); + + let mut order_map: HashMap> = HashMap::new(); + for rule in order_rules.iter() { + let entry = order_map.entry(rule[0]).or_insert(Vec::new()); + entry.push(rule[1]); + } + + let sort = |a: &u64, b: &u64| { + if order_map.get(&a).unwrap_or(&vec![]).contains(&b) { + Ordering::Less + } else if order_map.get(&b).unwrap_or(&vec![]).contains(&a) { + Ordering::Greater + } else { + Ordering::Equal + } + }; + let is_sorted = |l: &Vec| { + l.windows(2) + .all(|w| (sort)(&w[0], &w[1]) != Ordering::Greater) + }; + + let (correct, mut incorrect): (Vec>, Vec>) = + page_sets.into_iter().partition(is_sorted); + + incorrect.iter_mut().for_each(|set| set.sort_by(sort)); + + let sum_correct: u64 = correct.iter().map(|set| set[set.len() / 2]).sum(); + let sum_fixed: u64 = incorrect.iter().map(|set| set[set.len() / 2]).sum(); + + println!("Sum of Correct Middle Pages: {}", sum_correct); + println!("Sum of Fixed Middle Pages: {}", sum_fixed); +} diff --git a/src/main.rs b/src/main.rs index c5d3d2c..434db46 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,10 @@ mod day1; mod day2; mod day3; mod day4; +mod day5; fn main() { - day4::day4(); + day5::day5(); } pub fn input(day: u8) -> String {