From d752baf7a175d2eabe1fd42d6ba9100c72a4acf5 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Sun, 7 Jul 2024 11:57:55 +0200 Subject: [PATCH] day(25): add solution Signed-off-by: Matej Focko --- samples/day25.txt | 13 ++++ src/bin/day25.rs | 147 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 samples/day25.txt create mode 100644 src/bin/day25.rs diff --git a/samples/day25.txt b/samples/day25.txt new file mode 100644 index 0000000..f5bdcc2 --- /dev/null +++ b/samples/day25.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 \ No newline at end of file diff --git a/src/bin/day25.rs b/src/bin/day25.rs new file mode 100644 index 0000000..acfdc99 --- /dev/null +++ b/src/bin/day25.rs @@ -0,0 +1,147 @@ +use std::collections::{HashMap, VecDeque}; + +use aoc_2023::*; + +type Output1 = usize; +type Output2 = Output1; + +lazy_static! { + static ref EDGE_REGEX: Regex = Regex::new(r"(.*): (.*)").unwrap(); +} + +struct Day25 { + edges: Vec, + nodes: Vec<(usize, usize)>, +} + +impl Day25 { + fn neighbours(&self, u: usize) -> impl Iterator + '_ { + let (start, end) = self.nodes[u]; + (start..end).map(|idx| (idx, self.edges[idx])) + } + + fn furthest(&self, start: usize) -> usize { + let mut todo = VecDeque::new(); + todo.push_back(start); + + let mut seen = vec![false; self.nodes.len()]; + seen[start] = true; + + let mut result = start; + while let Some(u) = todo.pop_front() { + result = u; + + for (_, v) in self.neighbours(u) { + if !seen[v] { + todo.push_back(v); + seen[v] = true; + } + } + } + + result + } + + fn flow(&self, start: usize, end: usize) -> usize { + let mut todo = VecDeque::new(); + let mut path = Vec::new(); + let mut used = vec![false; self.edges.len()]; + + let mut result = 0; + + for _ in 0..4 { + todo.push_back((start, usize::MAX)); + result = 0; + + let mut seen = vec![false; self.nodes.len()]; + seen[start] = true; + + while let Some((u, head)) = todo.pop_front() { + result += 1; + + if u == end { + let mut index = head; + + while index != usize::MAX { + let (edge, next) = path[index]; + used[edge] = true; + index = next; + } + + break; + } + + for (edge, v) in self.neighbours(u) { + if !used[edge] && !seen[v] { + seen[v] = true; + todo.push_back((v, path.len())); + path.push((edge, head)); + } + } + } + + todo.clear(); + path.clear(); + } + + result + } +} + +impl Solution for Day25 { + fn new>(pathname: P) -> Self { + let mut mapping: HashMap = HashMap::new(); + + let mut graph: HashMap> = HashMap::new(); + let mut add_edge = |u, v| { + graph.entry(u).or_default().push(v); + }; + + let lines: Vec = file_to_lines(pathname); + for (u, vs) in lines.into_iter().map(|l| { + let (_, [src, dest]) = EDGE_REGEX.captures(&l).unwrap().extract(); + ( + src.to_owned(), + dest.split(' ').map(str::to_owned).collect_vec(), + ) + }) { + let next_idx = mapping.len(); + let u_idx = *mapping.entry(u.clone()).or_insert(next_idx); + + for v in vs { + let next_idx = mapping.len(); + let v_idx = *mapping.entry(v.clone()).or_insert(next_idx); + + add_edge(u_idx, v_idx); + add_edge(v_idx, u_idx); + } + } + + let mut edges = Vec::new(); + let mut nodes = vec![(usize::MAX, usize::MAX); mapping.len()]; + for (u, neighbours) in graph.into_iter() { + nodes[u] = (edges.len(), edges.len() + neighbours.len()); + edges.extend(neighbours); + } + + Self { edges, nodes } + } + + fn part_1(&mut self) -> Output1 { + let u = self.furthest(0); + let v = self.furthest(u); + + let size = self.flow(u, v); + size * (self.nodes.len() - size) + } + + fn part_2(&mut self) -> Output2 { + 2023 + } +} + +fn main() -> Result<()> { + Day25::main() +} + +test_sample!(day_25, Day25, 54, 2023);