From 95b654234ff7ccccca7569b374b9b1c6a8ae1144 Mon Sep 17 00:00:00 2001 From: Adrian Groh Date: Mon, 23 Dec 2024 13:15:12 +0100 Subject: [PATCH] Add day23 --- day23/Cargo.lock | 63 +++++++++++++++++++++++++++++++++++++++++ day23/Cargo.toml | 8 ++++++ day23/src/main.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 day23/Cargo.lock create mode 100644 day23/Cargo.toml create mode 100644 day23/src/main.rs diff --git a/day23/Cargo.lock b/day23/Cargo.lock new file mode 100644 index 0000000..1157acb --- /dev/null +++ b/day23/Cargo.lock @@ -0,0 +1,63 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "day23" +version = "0.1.0" +dependencies = [ + "itertools", + "petgraph", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "petgraph" +version = "0.6.5" +source = "git+https://github.com/qoqosz/petgraph?branch=feature%2Fmaximal_cliques#cee17df1398adeae9f4696d3f4caba5662b37d63" +dependencies = [ + "fixedbitset", + "indexmap", +] diff --git a/day23/Cargo.toml b/day23/Cargo.toml new file mode 100644 index 0000000..eb31ab9 --- /dev/null +++ b/day23/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "day23" +version = "0.1.0" +edition = "2021" + +[dependencies] +itertools = "0.13.0" +petgraph = { git = "https://github.com/qoqosz/petgraph", branch = "feature/maximal_cliques"} diff --git a/day23/src/main.rs b/day23/src/main.rs new file mode 100644 index 0000000..f727481 --- /dev/null +++ b/day23/src/main.rs @@ -0,0 +1,71 @@ +use std::collections::{HashMap, HashSet}; + +use itertools::Itertools; +use petgraph::algo::maximal_cliques; +use petgraph::prelude::*; + +fn parse(input: &str) -> Vec<(String, String)> { + input + .lines() + .map(|l| l.split_once("-").unwrap()) + .map(|(a, b)| (a.to_string(), b.to_string())) + .collect() +} + +fn build_graph(edges: Vec<(String, String)>) -> UnGraph { + let mut graph = UnGraph::new_undirected(); + let mut node_indices = HashMap::new(); + + for (a, b) in edges { + let from_index = *node_indices + .entry(a.clone()) + .or_insert_with(|| graph.add_node(a)); + let to_index = *node_indices + .entry(b.clone()) + .or_insert_with(|| graph.add_node(b)); + graph.add_edge(from_index, to_index, ()); + } + + graph +} + +fn part1(graph: &UnGraph) -> usize { + let mut cliques3 = HashSet::new(); + for edge in graph.edge_references() { + for &w in graph + .neighbors(edge.source()) + .collect::>() + .intersection(&graph.neighbors(edge.target()).collect::>()) + { + let mut clique3 = [edge.source(), edge.target(), w]; + clique3.sort_unstable(); + cliques3.insert(clique3); + } + } + cliques3 + .iter() + .filter(|clique| { + clique + .iter() + .any(|n_idx| graph.node_weight(*n_idx).unwrap().starts_with("t")) + }) + .count() +} + +fn part2(graph: &Graph) -> String { + maximal_cliques(graph) + .iter() + .max_by_key(|x| x.len()) + .unwrap() + .iter() + .map(|n_idx| graph.node_weight(*n_idx).unwrap().to_string()) + .sorted_unstable() + .join(",") +} + +fn main() { + let input = parse(include_str!("../input.txt")); + let graph = build_graph(input); + println!("{}", part1(&graph)); + println!("{}", part2(&graph)); +}