Skip to content

Commit 41ac51f

Browse files
committed
23th day (with Bron–Kerbosch algorithm)
1 parent d0398ef commit 41ac51f

File tree

1 file changed

+34
-41
lines changed

1 file changed

+34
-41
lines changed

src/bin/23.rs

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
advent_of_code::solution!(23);
22

3-
use advent_of_code::maneatingape::hash::*;
3+
use std::iter::once;
44

5-
use std::collections::BTreeSet;
5+
use advent_of_code::maneatingape::hash::*;
66

77
struct Computer {}
88

@@ -78,53 +78,46 @@ pub fn part_one(input: &str) -> Option<u32> {
7878
Some(result)
7979
}
8080

81-
pub fn part_two(input: &str) -> Option<String> {
82-
let nodes = parse_data(input);
83-
84-
let mut cache = FastSet::new();
85-
86-
let mut keys = nodes.keys().copied().collect::<Vec<_>>();
87-
keys.sort_by(|a, b| nodes[b].len().cmp(&nodes[a].len()));
88-
89-
let to_check = keys;
90-
let group = BTreeSet::new();
91-
let mut queue = vec![(to_check, group)];
92-
while let Some((c, g)) = queue.pop() {
93-
for i in 0..c.len() {
94-
let mut is_ok = true;
95-
for el in g.iter() {
96-
if !nodes[el].contains(&c[i]) {
97-
is_ok = false;
98-
break;
99-
}
100-
}
101-
102-
if is_ok {
103-
let mut new_g = g.clone();
104-
new_g.insert(c[i]);
81+
fn bors_kerbosch(
82+
r: Vec<usize>,
83+
p: FastSet<usize>,
84+
x: FastSet<usize>,
85+
g: &FastMap<usize, FastSet<usize>>,
86+
) -> Vec<usize> {
87+
if p.is_empty() && x.is_empty() {
88+
return r;
89+
}
10590

106-
if cache.contains(&new_g) {
107-
continue;
108-
}
91+
let mut max_result = vec![];
92+
let mut p = p;
93+
let mut x = x;
10994

110-
cache.insert(new_g.clone());
95+
let pivot = p.union(&x).max_by_key(|v| g[v].len()).unwrap();
11196

112-
let mut new_c = c.clone();
113-
new_c.remove(i);
97+
for v in p.difference(&g[pivot]).copied().collect::<Vec<_>>() {
98+
let next_r = r.iter().chain(once(&v)).copied().collect::<Vec<_>>();
99+
let next_p = p.intersection(&g[&v]).copied().collect::<FastSet<_>>();
100+
let next_x = x.intersection(&g[&v]).copied().collect::<FastSet<_>>();
114101

115-
queue.push((new_c, new_g));
116-
}
102+
let result = bors_kerbosch(next_r, next_p, next_x, g);
103+
if result.len() > max_result.len() {
104+
max_result = result;
117105
}
106+
107+
p.remove(&v);
108+
x.insert(v);
118109
}
119110

120-
let mut result = cache
121-
.iter()
122-
.max_by(|x, y| x.len().cmp(&y.len()))
123-
.unwrap()
124-
.iter()
125-
.map(|&x| Computer::decode(x))
126-
.collect::<Vec<_>>();
111+
max_result
112+
}
113+
114+
pub fn part_two(input: &str) -> Option<String> {
115+
let nodes = parse_data(input);
116+
117+
let keys = nodes.keys().copied().collect::<FastSet<_>>();
118+
let result = bors_kerbosch(vec![], keys, FastSet::new(), &nodes);
127119

120+
let mut result = result.into_iter().map(Computer::decode).collect::<Vec<_>>();
128121
result.sort_unstable();
129122

130123
let result = result.join(",");

0 commit comments

Comments
 (0)