diff --git a/src/main.rs b/src/main.rs index 450f27f..cd813e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -203,6 +203,89 @@ mod day4 { } } +mod day5 { + use std::{ + cmp::Ordering, + collections::{HashMap, HashSet}, + }; + + use itertools::Itertools; + + type Rules = HashMap>; + + fn parse_rules<'a>(lines: &mut impl Iterator) -> Rules { + let mut rules: Rules = HashMap::new(); + for rule in lines.by_ref().take_while(|s| !s.is_empty()) { + let vals = rule.split_once('|').unwrap(); + let (before, after) = (vals.0.parse().unwrap(), vals.1.parse().unwrap()); + rules.entry(before).or_default().insert(after); + } + rules + } + + fn check_update(update: &[i32], rules: &Rules) -> bool { + for (i, val) in update.iter().enumerate() { + let Some(local_rules) = rules.get(val) else { + continue; + }; + if update[..i].iter().any(|elem| local_rules.contains(elem)) { + return false; + } + } + true + } + + fn parse_updates<'a>( + lines: impl Iterator + 'a, + ) -> impl Iterator> + 'a { + lines.map(|line| { + line.trim() + .split(',') + .map(|num| num.parse::().unwrap()) + .collect_vec() + }) + } + + #[allow(dead_code)] + pub fn task1() { + let data = std::fs::read_to_string("input.txt").unwrap(); + let mut lines = data.lines(); + let rules = parse_rules(&mut lines); + let result: i32 = parse_updates(lines) + .filter(|u| check_update(u, &rules)) + .map(|u| u[u.len() / 2]) + .sum(); + println!("{result}"); + } + + #[allow(dead_code)] + pub fn task2() { + let data = std::fs::read_to_string("input.txt").unwrap(); + let mut lines = data.lines(); + let rules = parse_rules(&mut lines); + let result: i32 = parse_updates(lines) + .filter(|u| !check_update(u, &rules)) + .map(|mut u| { + u.sort_unstable_by(|a, b| { + if let Some(rule) = rules.get(a) { + if rule.contains(b) { + return Ordering::Less; + } + } + if let Some(rule) = rules.get(b) { + if rule.contains(a) { + return Ordering::Greater; + } + } + Ordering::Equal + }); + u[u.len() / 2] + }) + .sum(); + println!("{result}"); + } +} + fn main() { // day1::task1(); // day1::task1(); @@ -210,6 +293,8 @@ fn main() { // day2::task2(); // day3::task1(); // day3::task2(); - day4::task1(); - day4::task2(); + // day4::task1(); + // day4::task2(); + day5::task1(); + day5::task2(); }