This commit is contained in:
Moritz Hölting 2023-12-25 11:36:39 +01:00
parent a95dffbf5c
commit a6f26aa02c
4 changed files with 1368 additions and 6 deletions

20
Cargo.lock generated
View File

@ -311,6 +311,14 @@ dependencies = [
"z3",
]
[[package]]
name = "day-25"
version = "0.0.0"
dependencies = [
"indoc",
"pathfinding",
]
[[package]]
name = "deprecate-until"
version = "0.1.1"
@ -581,9 +589,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "pathfinding"
version = "4.6.0"
version = "4.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ea07a6e677e47d6a84724d4fdf88b1e37fcb49ac94e236d7caeefd8fee75c8a"
checksum = "f6f4a3f5089b981000cb50ec24320faf7a19649a45e8730e4adf49f78f066528"
dependencies = [
"deprecate-until",
"fixedbitset",
@ -726,18 +734,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.50"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
dependencies = [
"proc-macro2",
"quote",

12
day-25/Cargo.toml Normal file
View File

@ -0,0 +1,12 @@
[package]
name = "day-25"
version = "0.0.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
pathfinding = "4.8.0"
[dev-dependencies]
indoc.workspace = true

1215
day-25/src/input.txt Normal file

File diff suppressed because it is too large Load Diff

127
day-25/src/main.rs Normal file
View File

@ -0,0 +1,127 @@
use pathfinding::prelude::bfs;
use std::collections::{HashMap, HashSet};
/// Puzzle consists only of one part today.
fn main() {
println!("{}", part1(include_str!("./input.txt")));
}
fn part1(input: &str) -> usize {
let mut graph = graph_from_input(input);
for i in 1..graph.len() {
let paths = (0..3)
.map(|_| {
let path = bfs(
&0,
|node| graph[node].iter().copied(),
|&node| node == i as u16,
)
.unwrap();
// remove chosen edges
path.windows(2).for_each(|e| {
graph.get_mut(&e[0]).unwrap().remove(&e[1]);
graph.get_mut(&e[1]).unwrap().remove(&e[0]);
});
path
})
.collect::<Vec<_>>();
// check if graph is still connected
match bfs(
&0,
|node| graph[node].iter().copied(),
|&node| node == i as u16,
) {
Some(_) => (),
None => {
let size_a = connected_count(&graph);
let size_b = graph.len() - size_a;
return size_a * size_b;
}
}
// restore edges
paths.into_iter().for_each(|path| {
path.windows(2).for_each(|e| {
graph.get_mut(&e[0]).unwrap().insert(e[1]);
graph.get_mut(&e[1]).unwrap().insert(e[0]);
});
});
}
0
}
type Graph = HashMap<u16, HashSet<u16>>;
fn graph_from_input(input: &str) -> Graph {
let mut node_ids = HashMap::new();
let mut nodes = HashMap::new();
for line in input.lines() {
let (start, ends) = line.split_once(": ").unwrap();
for end in ends.split(' ') {
let id = node_ids.len() as u16;
node_ids.entry(end).or_insert(id);
}
let id = node_ids.len() as u16;
node_ids.entry(start).or_insert(id);
let start = node_ids[&start];
let ends = ends.split(' ').map(|e| node_ids[&e]);
for end in ends.clone() {
nodes.entry(end).or_insert_with(HashSet::new).insert(start);
}
nodes.entry(start).or_insert_with(HashSet::new).extend(ends);
}
nodes
}
fn connected_count(nodes: &Graph) -> usize {
let mut visited = HashSet::new();
let mut queue = Vec::new();
queue.push(*nodes.keys().next().unwrap());
while let Some(node) = queue.pop() {
if !visited.insert(node) {
continue;
}
for &neighbor in nodes[&node].iter() {
queue.push(neighbor);
}
}
visited.len()
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
#[test]
fn test_part1() {
assert_eq!(
part1(indoc!(
"
jqt: rhn xhk nvd
rsh: frs pzl lsr
xhk: hfx
cmg: qnr nvd lhk bvb
rhn: xhk bvb hfx
bvb: xhk hfx
pzl: lsr hfx nvd
qnr: nvd
ntq: jqt hfx bvb xhk
nvd: lhk
lsr: lhk
rzs: qnr cmg lsr rsh
frs: qnr lhk lsr
"
)),
54
);
}
}