From 50a197856aa32e52594b2314079a9c7c60eb4960 Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Mon, 23 Dec 2024 00:23:12 -0800 Subject: [PATCH] day23: part 2 working (i think) but too slow --- src/day23.rs | 79 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 5 deletions(-) diff --git a/src/day23.rs b/src/day23.rs index 6dbbbdf..0dd08c8 100644 --- a/src/day23.rs +++ b/src/day23.rs @@ -1,7 +1,12 @@ -use std::fmt::Debug; +use std::{ + collections::VecDeque, + fmt::{Debug, Display}, +}; use aoc_runner_derive::aoc; +use indicatif::{ParallelProgressIterator, ProgressBar, ProgressIterator}; use itertools::Itertools; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use rustc_hash::{FxHashMap, FxHashSet}; #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] @@ -13,6 +18,12 @@ impl Debug for Node { } } +impl Display for Node { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("{}", self.0.iter().join(""))) + } +} + impl From<[char; 2]> for Node { fn from(value: [char; 2]) -> Self { Node(value) @@ -51,6 +62,44 @@ impl Network { } sets } + fn node_groups(&self, n: &Node, adjacent_set: FxHashSet) -> Option> { + // println!("{:?} {:?}", n, adjacent_set); + let neigh = FxHashSet::from_iter(self.edges.get(n).unwrap().iter().map(|n| *n)); + let intersection = FxHashSet::from_iter(adjacent_set.intersection(&neigh).map(|n| *n)); + if intersection != adjacent_set { + return Some(adjacent_set); + } + let mut next_adj_set = adjacent_set.clone(); + next_adj_set.insert(*n); + neigh + .iter() + .filter(|neigh_n| !next_adj_set.contains(neigh_n)) + .filter_map(|neigh_n| self.node_groups(neigh_n, next_adj_set.clone())) + .max_by(|a, b| a.len().cmp(&b.len())) + } + fn born_kerbosch(&self, r: FxHashSet, mut p: FxHashSet, mut x: FxHashSet) -> FxHashSet { + if p.is_empty() && r.is_empty() { + return r; + } + let p_iter = p.clone(); // se we can modify p + for node in &p_iter { + let mut new_r = r.clone(); + new_r.insert(*node); + let new_p = FxHashSet::from_iter( + p.intersection(&FxHashSet::from_iter(self.edges.get(&node).unwrap().iter().map(|n| *n))) + .map(|n| *n), + ); + let new_x = FxHashSet::from_iter( + x.intersection(&FxHashSet::from_iter(self.edges.get(&node).unwrap().iter().map(|n| *n))) + .map(|n| *n), + ); + + self.born_kerbosch(new_r, new_p, new_x); + p.remove(&node); + x.insert(*node); + } + r + } } impl From<&str> for Network { @@ -83,17 +132,37 @@ fn parse(input: &str) -> Network { #[aoc(day23, part1)] pub fn part1(input: &str) -> i64 { let network = parse(input); - println!("edges: {:?}", network.edges); + // println!("edges: {:?}", network.edges); let sets = network.groups_3(); let t_count = sets.iter().filter(|set| set.iter().any(|s| s.0[0] == 't')).count(); - println!("groups: {:?}", sets); - + // println!("groups: {:?}", sets); + t_count as i64 } #[aoc(day23, part2)] pub fn part2(input: &str) -> String { - todo!() + let network = parse(input); + let mut best = FxHashSet::default(); + let mut node_queue = network.nodes.clone(); + let progress = ProgressBar::new(network.nodes.len() as u64); + while let Some(node) = node_queue.pop() { + progress.inc(1); + let net = network.node_groups(&node, FxHashSet::default()).unwrap(); + println!("NODE {} best: {:?}", node, net); + for checked in &net { + if let Some(idx) = node_queue.iter().position(|to_remove| to_remove == checked) { + node_queue.remove(idx); + progress.inc(1); + } + } + if net.len() > best.len() { + best = net; + } + } + // println!("{:?}", network.node_groups(&Node(['k', 'a']), FxHashSet::default())); + println!("best: {:?}", best); + String::new() } #[cfg(test)]