Untitled
unknown
rust
2 months ago
3.9 kB
37
Indexable
pub fn solution(test: bool) -> ((usize, Duration), (usize, Duration)) { let lines; if test { lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_23_test.txt"); } else { lines = include_str!("../../../AdventOfCodeInputs/problem_inputs_2024/day_23.txt"); } let mut graph: UnGraph<&str, ()> = UnGraph::default(); let mut node_index: FxHashMap<&str, NodeIndex> = FxHashMap::default(); for line in lines.lines() { let (node1, node2) = line.split_once("-").unwrap(); let node1_index = *node_index .entry(node1) .or_insert_with(|| graph.add_node(node1)); let node2_index = *node_index .entry(node2) .or_insert_with(|| graph.add_node(node2)); graph.add_edge(node1_index, node2_index, ()); } (solve01(&graph), solve02(&graph)) } fn solve01(graph: &UnGraph<&str, ()>) -> (usize, Duration) { let now = Instant::now(); let triangles = find_triangles(&graph); let triangles_with_t = triangles .iter() .filter(|(a, b, c)| a.starts_with('t') || b.starts_with('t') || c.starts_with('t')) .collect_vec(); (triangles_with_t.len(), now.elapsed()) } fn solve02(graph: &UnGraph<&str, ()>) -> (usize, Duration) { let now = Instant::now(); let max_clique = find_max_clique(&graph); let max_clique_str = max_clique.join(","); dbg!(&max_clique_str); (0, now.elapsed()) } fn find_triangles(graph: &UnGraph<&str, ()>) -> Vec<(String, String, String)> { let mut triangles = Vec::new(); for edge in graph.edge_references() { let (u, v) = (edge.source(), edge.target()); // Check for a common neighbor that forms a triangle for &neighbor in graph.neighbors(u).collect::<Vec<_>>().iter() { if graph.contains_edge(neighbor, v) { // Sort the vertices to avoid duplicates let mut triangle = vec![ graph[u].to_string(), graph[v].to_string(), graph[neighbor].to_string(), ]; triangle.sort(); triangles.push(( triangle[0].clone(), triangle[1].clone(), triangle[2].clone(), )); } } } // Remove duplicate triangles triangles.sort(); triangles.dedup(); triangles } fn bron_kerbosch( graph: &UnGraph<&str, ()>, r: FxHashSet<usize>, p: &mut FxHashSet<usize>, x: &mut FxHashSet<usize>, max_cliques: &mut Vec<FxHashSet<usize>>, ) { if p.is_empty() && x.is_empty() { max_cliques.push(r); return; } let p_iter = p.clone(); for v in p_iter { let mut r_new = r.clone(); r_new.insert(v); let neighbors: FxHashSet<_> = graph .neighbors(graph.from_index(v)) .map(|n| graph.to_index(n)) .collect(); let mut p_new: FxHashSet<_> = p.intersection(&neighbors).cloned().collect(); let mut x_new: FxHashSet<_> = x.intersection(&neighbors).cloned().collect(); bron_kerbosch(graph, r_new, &mut p_new, &mut x_new, max_cliques); p.remove(&v); x.insert(v); } } fn find_max_clique(graph: &UnGraph<&str, ()>) -> Vec<String> { let mut max_cliques = Vec::with_capacity(512); let mut nodes: FxHashSet<_> = (0..graph.node_count()).collect(); bron_kerbosch( graph, FxHashSet::default(), &mut nodes, &mut FxHashSet::default(), &mut max_cliques, ); let largest_clique = max_cliques .into_iter() .max_by_key(|c| c.len()) .unwrap_or_default(); largest_clique .into_iter() .map(|i| graph.node_weight(graph.from_index(i)).unwrap().to_string()) .sorted() .collect() }
Editor is loading...
Leave a Comment