day 25
This commit is contained in:
parent
a95dffbf5c
commit
a6f26aa02c
|
@ -311,6 +311,14 @@ dependencies = [
|
||||||
"z3",
|
"z3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day-25"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"indoc",
|
||||||
|
"pathfinding",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deprecate-until"
|
name = "deprecate-until"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -581,9 +589,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pathfinding"
|
name = "pathfinding"
|
||||||
version = "4.6.0"
|
version = "4.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ea07a6e677e47d6a84724d4fdf88b1e37fcb49ac94e236d7caeefd8fee75c8a"
|
checksum = "f6f4a3f5089b981000cb50ec24320faf7a19649a45e8730e4adf49f78f066528"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deprecate-until",
|
"deprecate-until",
|
||||||
"fixedbitset",
|
"fixedbitset",
|
||||||
|
@ -726,18 +734,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.50"
|
version = "1.0.51"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.50"
|
version = "1.0.51"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue