This commit is contained in:
nora 2024-12-07 11:48:56 +01:00
parent f5bd38d549
commit a83c2f53c9
3 changed files with 19 additions and 27 deletions

1
2024/Cargo.lock generated
View file

@ -158,6 +158,7 @@ dependencies = [
"divan", "divan",
"helper", "helper",
"nom", "nom",
"rustc-hash",
] ]
[[package]] [[package]]

View file

@ -9,6 +9,7 @@ edition = "2021"
nom.workspace = true nom.workspace = true
helper.workspace = true helper.workspace = true
divan.workspace = true divan.workspace = true
rustc-hash = "2.1.0"
[[bench]] [[bench]]
name = "benches" name = "benches"

View file

@ -1,4 +1,4 @@
use std::collections::HashMap; use rustc_hash::FxHashMap;
use helper::{parse_unwrap, Day, IteratorExt, Variants}; use helper::{parse_unwrap, Day, IteratorExt, Variants};
@ -49,30 +49,27 @@ fn part1(input: &str) -> u64 {
} }
fn build_nodes( fn build_nodes(
nodes_lookup: &mut FxHashMap<u64, usize>,
edges: &mut Vec<Vec<usize>>,
rules: impl Iterator<Item = (u64, u64)>, rules: impl Iterator<Item = (u64, u64)>,
) -> (HashMap<u64, usize>, Vec<u64>, Vec<Vec<usize>>) { ) {
let mut nodes_lookup = HashMap::new(); nodes_lookup.clear();
let mut nodes = Vec::new(); edges.clear();
let mut edges = Vec::<Vec<_>>::new();
for (first, then) in rules { for (first, then) in rules {
let first = *nodes_lookup.entry(first).or_insert_with(|| { let first = *nodes_lookup.entry(first).or_insert_with(|| {
nodes.push(first); edges.push(Vec::default());
edges.push(Vec::new()); edges.len() - 1
nodes.len() - 1
}); });
let then = *nodes_lookup.entry(then).or_insert_with(|| { let then = *nodes_lookup.entry(then).or_insert_with(|| {
nodes.push(then); edges.push(Vec::default());
edges.push(Vec::new()); edges.len() - 1
nodes.len() - 1
}); });
if !edges[first].contains(&then) { if !edges[first].contains(&then) {
edges[first].push(then); edges[first].push(then);
} }
} }
assert_eq!(nodes_lookup.len(), nodes.len()); assert_eq!(nodes_lookup.len(), edges.len());
assert_eq!(nodes.len(), edges.len());
(nodes_lookup, nodes, edges)
} }
/* /*
@ -106,21 +103,14 @@ fn part1(input: &str) -> u64 {
dbg!(all_sorted); dbg!(all_sorted);
*/ */
fn must_be_before(edges: &[Vec<usize>], nodes: &[u64], before: usize, after: usize) -> bool { let mut nodes_lookup = FxHashMap::default();
if edges[before].contains(&after) { let mut edges = Vec::new();
return true;
}
for &child in &edges[before] {
if must_be_before(edges, nodes, child, after) {
return true;
}
}
false
}
let mut result = 0; let mut result = 0;
for update in updates { for update in updates {
let (nodes_lookup, nodes, edges) = build_nodes( build_nodes(
&mut nodes_lookup,
&mut edges,
rules rules
.iter() .iter()
.filter(|(a, b)| update.contains(&a) && update.contains(&b)) .filter(|(a, b)| update.contains(&a) && update.contains(&b))
@ -130,7 +120,7 @@ fn part1(input: &str) -> u64 {
let mut is_bad = false; let mut is_bad = false;
for ab in update.windows(2) { for ab in update.windows(2) {
let (a, b) = (ab[0], ab[1]); let (a, b) = (ab[0], ab[1]);
if must_be_before(&edges, &nodes, nodes_lookup[&b], nodes_lookup[&a]) { if edges[nodes_lookup[&b]].contains(&nodes_lookup[&a]) {
is_bad = true; is_bad = true;
break; break;
} }