From 0000043002495425405229757340a0644803ed62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Jane=C5=BEi=C4=8D?= Date: Mon, 25 Dec 2023 08:58:42 +0100 Subject: [PATCH] solution: day 25 --- data/examples/25.txt | 13 +++++++ src/bin/25.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 data/examples/25.txt create mode 100644 src/bin/25.rs diff --git a/data/examples/25.txt b/data/examples/25.txt new file mode 100644 index 000000000..bbfda0b --- /dev/null +++ b/data/examples/25.txt @@ -0,0 +1,13 @@ +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 diff --git a/src/bin/25.rs b/src/bin/25.rs new file mode 100644 index 000000000..a9f30cd --- /dev/null +++ b/src/bin/25.rs @@ -0,0 +1,80 @@ +use std::collections::HashMap; + +fn build_graph(input: &str, skips: &[(&str, &str)]) -> Vec> { + let mut nodes = Vec::new(); + let mut mapper = HashMap::new(); + + for (node, neighs) in input.lines().filter_map(|x| x.split_once(": ")) { + if !mapper.contains_key(node) { + mapper.insert(node, nodes.len()); + nodes.push(Vec::new()); + } + + let index_a = mapper[node]; + + for n in neighs.split(' ') { + if !mapper.contains_key(n) { + mapper.insert(n, nodes.len()); + nodes.push(Vec::new()); + } + + if skips.contains(&(node, n)) || skips.contains(&(n, node)) { + continue; + } + + let index_b = mapper[n]; + nodes[index_a].push(index_b); + nodes[index_b].push(index_a); + } + } + + nodes +} + +pub fn part_one_wrapped(input: &str, skips: &[(&str, &str)]) -> Option { + let nodes = build_graph(input, skips); + + let mut visited = vec![false; nodes.len()]; + let mut stack = vec![0]; + + while let Some(node) = stack.pop() { + if visited[node] { + continue; + } + visited[node] = true; + for n in nodes[node].iter().copied() { + if !visited[n] { + stack.push(n); + } + } + } + + let counter = visited.iter().copied().filter(|&x| x).count(); + Some((nodes.len() - counter) * counter) +} + +pub fn part_one(input: &str) -> Option { + // to figure out which nodes to skip + // echo "graph A {\n$(cat data/inputs/25.txt)\n}" | \ + // sed 's/\(.*\): \(.*\)$/\1 -- {\2}/' | \ + // dot -Tsvg -Kneato > graph.svg + let skips = [("sfm", "vmt"), ("vph", "mfc"), ("fql", "rmg")]; + part_one_wrapped(input, &skips) +} + +pub fn part_two(_input: &str) -> Option { + Some("Happy chrismas!".into()) +} + +aoc::solution!(25); + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_part_one() { + let skips = [("pzl", "hfx"), ("bvb", "cmg"), ("nvd", "jqt")]; + let input = aoc::template::read_file("examples", 25); + assert_eq!(part_one_wrapped(&input, &skips), Some(54)); + } +}