day 5 part 1 works

This commit is contained in:
nora 2024-12-07 11:27:23 +01:00
parent 2a31efc842
commit f5bd38d549
2 changed files with 124 additions and 2 deletions

View file

@ -0,0 +1,28 @@
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

View file

@ -1,3 +1,5 @@
use std::collections::HashMap;
use helper::{parse_unwrap, Day, IteratorExt, Variants}; use helper::{parse_unwrap, Day, IteratorExt, Variants};
pub fn main() { pub fn main() {
@ -46,7 +48,99 @@ fn part1(input: &str) -> u64 {
updates.push(numbers); updates.push(numbers);
} }
0 fn build_nodes(
rules: impl Iterator<Item = (u64, u64)>,
) -> (HashMap<u64, usize>, Vec<u64>, Vec<Vec<usize>>) {
let mut nodes_lookup = HashMap::new();
let mut nodes = Vec::new();
let mut edges = Vec::<Vec<_>>::new();
for (first, then) in rules {
let first = *nodes_lookup.entry(first).or_insert_with(|| {
nodes.push(first);
edges.push(Vec::new());
nodes.len() - 1
});
let then = *nodes_lookup.entry(then).or_insert_with(|| {
nodes.push(then);
edges.push(Vec::new());
nodes.len() - 1
});
if !edges[first].contains(&then) {
edges[first].push(then);
}
}
assert_eq!(nodes_lookup.len(), nodes.len());
assert_eq!(nodes.len(), edges.len());
(nodes_lookup, nodes, edges)
}
/*
let mut all_sorted = Vec::new();
let mut marked = vec![false; nodes.len()];
let mut worklist = VecDeque::new();
while let Some((i, _)) = marked
.iter()
.enumerate()
.find(|(_, is_marked)| !**is_marked)
{
let mut temporary_ordering = Vec::new();
worklist.clear();
worklist.push_back(i);
while let Some(item) = worklist.pop_front() {
if marked[item] {
continue;
}
temporary_ordering.push(nodes[item]);
for child in edges[item].iter().rev() {
worklist.push_front(*child);
}
marked[item] = true;
}
all_sorted.extend_from_slice(&temporary_ordering);
}
dbg!(all_sorted);
*/
fn must_be_before(edges: &[Vec<usize>], nodes: &[u64], before: usize, after: usize) -> bool {
if edges[before].contains(&after) {
return true;
}
for &child in &edges[before] {
if must_be_before(edges, nodes, child, after) {
return true;
}
}
false
}
let mut result = 0;
for update in updates {
let (nodes_lookup, nodes, edges) = build_nodes(
rules
.iter()
.filter(|(a, b)| update.contains(&a) && update.contains(&b))
.copied(),
);
let mut is_bad = false;
for ab in update.windows(2) {
let (a, b) = (ab[0], ab[1]);
if must_be_before(&edges, &nodes, nodes_lookup[&b], nodes_lookup[&a]) {
is_bad = true;
break;
}
}
if !is_bad {
result += update[update.len() / 2];
}
}
result
} }
fn part2(_input: &str) -> u64 { fn part2(_input: &str) -> u64 {
@ -57,7 +151,7 @@ helper::tests! {
day05 Day05; day05 Day05;
part1 { part1 {
small => 143; small => 143;
default => 0; default => 4959;
} }
part2 { part2 {
small => 0; small => 0;