mirror of
https://github.com/Noratrieb/advent-of-code.git
synced 2026-01-14 17:45:02 +01:00
d6p2
This commit is contained in:
parent
d23c534f5d
commit
c4518496d3
1 changed files with 97 additions and 5 deletions
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
use helper::{parse_unwrap, Day, IteratorExt, Variants};
|
use helper::{parse_unwrap, Day, IteratorExt, Variants};
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
|
@ -12,7 +14,7 @@ helper::define_variants! {
|
||||||
basic => crate::part1, sample_count=1000;
|
basic => crate::part1, sample_count=1000;
|
||||||
}
|
}
|
||||||
part2 {
|
part2 {
|
||||||
basic => crate::part2;
|
basic => crate::part2, sample_count=1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,8 +126,98 @@ fn part1(input: &str) -> u64 {
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(_input: &str) -> u64 {
|
fn part2(input: &str) -> u64 {
|
||||||
0
|
struct Update {
|
||||||
|
values: Vec<u64>,
|
||||||
|
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::<Vec<_>>();
|
||||||
|
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<Item = (u64, u64)>) {
|
||||||
|
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<u64>,
|
||||||
|
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! {
|
helper::tests! {
|
||||||
|
|
@ -135,8 +227,8 @@ helper::tests! {
|
||||||
default => 4959;
|
default => 4959;
|
||||||
}
|
}
|
||||||
part2 {
|
part2 {
|
||||||
small => 0;
|
small => 123;
|
||||||
default => 0;
|
default => 4655;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
helper::benchmarks! {}
|
helper::benchmarks! {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue