advent_of_code_2024/src/day5.rs

48 lines
1.6 KiB
Rust

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<Vec<u64>> = input_parts[0]
.lines()
.filter(|line| !line.is_empty())
.map(|line| line.split("|").map(|x| x.parse::<u64>().unwrap()).collect())
.collect();
let page_sets: Vec<Vec<u64>> = input_parts[1]
.lines()
.filter(|line| !line.is_empty())
.map(|line| line.split(",").map(|x| x.parse::<u64>().unwrap()).collect())
.collect();
let mut order_map: HashMap<u64, Vec<u64>> = 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<u64>| {
l.windows(2)
.all(|w| (sort)(&w[0], &w[1]) != Ordering::Greater)
};
let (correct, mut incorrect): (Vec<Vec<u64>>, Vec<Vec<u64>>) =
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);
}