From c4518496d3c5794d0125a26472946e8d0acd5120 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:19:30 +0100 Subject: [PATCH] d6p2 --- 2024/day05/src/lib.rs | 102 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/2024/day05/src/lib.rs b/2024/day05/src/lib.rs index a6751d2..8c7fadc 100644 --- a/2024/day05/src/lib.rs +++ b/2024/day05/src/lib.rs @@ -1,3 +1,5 @@ +use std::collections::VecDeque; + use helper::{parse_unwrap, Day, IteratorExt, Variants}; pub fn main() { @@ -12,7 +14,7 @@ helper::define_variants! { basic => crate::part1, sample_count=1000; } part2 { - basic => crate::part2; + basic => crate::part2, sample_count=1000; } } @@ -124,8 +126,98 @@ fn part1(input: &str) -> u64 { result } -fn part2(_input: &str) -> u64 { - 0 +fn part2(input: &str) -> u64 { + struct Update { + values: Vec, + set: [bool; 100], + } + + let mut rules = Vec::new(); + let mut updates = Vec::new(); + let mut lines = input.lines(); + while let Some(line) = lines.next() { + if line.is_empty() { + break; + } + let values = line + .split('|') + .collect_array::<2>() + .unwrap() + .map(parse_unwrap); + rules.push((values[0], values[1])); + } + while let Some(line) = lines.next() { + let values = line.split(",").map(parse_unwrap).collect::>(); + let mut set = [false; 100]; + for value in &values { + set[*value as usize] = true; + } + updates.push(Update { values, set }); + } + + fn build_nodes(edges: &mut Vec<[bool; 100]>, rules: impl Iterator) { + edges.clear(); + + edges.resize(100, [false; 100]); + + for (first, then) in rules { + edges[first as usize][then as usize] = true; + } + } + + let mut edges = Vec::new(); + + let mut result = 0; + for update in updates { + build_nodes( + &mut edges, + rules + .iter() + .filter(|(a, b)| update.set[*a as usize] && update.set[*b as usize]) + .copied(), + ); + + let mut is_bad = false; + for ab in update.values.windows(2) { + let (a, b) = (ab[0], ab[1]); + if edges[b as usize][a as usize] { + is_bad = true; + break; + } + } + if is_bad { + // do Topological sort: + // https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search + let mut all_sorted = VecDeque::new(); + let mut marked = [false; 100]; + + fn visit( + all_sorted: &mut VecDeque, + marked: &mut [bool; 100], + edges: &[[bool; 100]], + node: usize, + ) { + if marked[node] { + return; + } + + for (child, _) in edges[node].iter().enumerate().filter(|(_, edge)| **edge) { + visit(all_sorted, marked, edges, child); + } + + marked[node] = true; + all_sorted.push_front(node as u64); + } + + while let Some(next) = update.values.iter().find(|value| !marked[**value as usize]) { + visit(&mut all_sorted, &mut marked, &edges, *next as usize); + } + + result += all_sorted[all_sorted.len() / 2]; + } + } + + result } helper::tests! { @@ -135,8 +227,8 @@ helper::tests! { default => 4959; } part2 { - small => 0; - default => 0; + small => 123; + default => 4655; } } helper::benchmarks! {}