day 25
This commit is contained in:
parent
a95dffbf5c
commit
a6f26aa02c
|
@ -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",
|
||||
|
|
|
@ -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