1
0
Fork 0

day(25): add solution

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2024-07-07 11:57:55 +02:00
parent a61866c12e
commit d752baf7a1
Signed by: mfocko
SSH key fingerprint: SHA256:5YXD7WbPuK60gxnG6DjAwJiS9+swoWj33/HFu8g8JVo
2 changed files with 160 additions and 0 deletions

13
samples/day25.txt Normal file
View file

@ -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

147
src/bin/day25.rs Normal file
View file

@ -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<usize>,
nodes: Vec<(usize, usize)>,
}
impl Day25 {
fn neighbours(&self, u: usize) -> impl Iterator<Item = (usize, usize)> + '_ {
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<Output1, Output2> for Day25 {
fn new<P: AsRef<Path>>(pathname: P) -> Self {
let mut mapping: HashMap<String, usize> = HashMap::new();
let mut graph: HashMap<usize, Vec<usize>> = HashMap::new();
let mut add_edge = |u, v| {
graph.entry(u).or_default().push(v);
};
let lines: Vec<String> = 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);