From d3bade1bddb9ea57dda585fc366526536a7114b7 Mon Sep 17 00:00:00 2001 From: Keenan Tims Date: Mon, 23 Dec 2024 00:54:13 -0800 Subject: [PATCH] day23: part 2 - bron kerbosch solution --- .aoc_tiles/tiles/2024/23.png | Bin 7699 -> 9365 bytes README.md | 2 +- src/day23.rs | 86 ++++++++++++----------------------- 3 files changed, 31 insertions(+), 57 deletions(-) diff --git a/.aoc_tiles/tiles/2024/23.png b/.aoc_tiles/tiles/2024/23.png index e8f4326276a6522e4fcfae3b3d8fb2686bab706d..bc4cac91f405049f863d26c632d0a199fde33904 100644 GIT binary patch literal 9365 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%0ASg9T0rC(YP8#PKW8A4Em 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 P00000NkvXXu0mjfVeCQ? literal 7699 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 diff --git a/README.md b/README.md index f23874d..c3d691c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- 2024 - 44 ⭐ - Rust + 2024 - 45 ⭐ - Rust

diff --git a/src/day23.rs b/src/day23.rs index 0dd08c8..8829984 100644 --- a/src/day23.rs +++ b/src/day23.rs @@ -1,13 +1,7 @@ -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}; +use std::fmt::{Debug, Display}; #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] struct Node([char; 2]); @@ -62,43 +56,37 @@ 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); + fn bron_kerbosch( + &self, + r: FxHashSet, + mut p: FxHashSet, + mut x: FxHashSet, + ) -> Vec> { + let mut results = Vec::new(); + if p.is_empty() && x.is_empty() { + return vec![r]; } - 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 + let p_iter = p.clone(); // so 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); + let neighbours = FxHashSet::from_iter(self.edges.get(&node).unwrap().iter().map(|n| *n)); + let new_p = FxHashSet::from_iter(p.intersection(&neighbours).map(|n| *n)); + let new_x = FxHashSet::from_iter(x.intersection(&neighbours).map(|n| *n)); + + results.extend(self.bron_kerbosch(new_r, new_p, new_x).into_iter()); p.remove(&node); x.insert(*node); } - r + results + } + fn maximal_subgraphs(&self) -> Vec> { + self.bron_kerbosch( + FxHashSet::default(), + FxHashSet::from_iter(self.nodes.iter().map(|n| *n)), + FxHashSet::default(), + ) } } @@ -143,26 +131,12 @@ pub fn part1(input: &str) -> i64 { #[aoc(day23, part2)] pub fn part2(input: &str) -> String { 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() + let best_sets = network.maximal_subgraphs(); + let largest_set = best_sets.iter().max_by(|a, b| a.len().cmp(&b.len())).unwrap(); + let mut largest = largest_set.iter().collect_vec(); + largest.sort(); + println!("best: {:?}", largest); + largest.iter().join(",") } #[cfg(test)]