From 263f80e6a3b14694ee40ae51821a4ace9009bde9 Mon Sep 17 00:00:00 2001 From: Lol3rrr Date: Fri, 9 Jan 2026 19:49:23 +0100 Subject: [PATCH] Implement 2025 - Day 7 - Part 2 --- 2025/07.rs | 93 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 30 deletions(-) diff --git a/2025/07.rs b/2025/07.rs index e76ee4b..c82b288 100644 --- a/2025/07.rs +++ b/2025/07.rs @@ -1,6 +1,14 @@ ---cargo +[profile.dev] +opt-level = 3 + +[dependencies] +nalgebra = "0.34" --- +use nalgebra::DMatrix; +use std::collections::HashMap; + static CONTENT: &'static str = include_str!("./inputs/07_1.txt"); #[derive(Debug, PartialEq)] @@ -21,47 +29,72 @@ fn main() { }).collect::>() }).collect(); - println!("Grid: {:?}", grid); + let height = grid.len(); + let width = grid[0].len(); - // (x, y) - let source = grid.iter().enumerate().flat_map(|(y, row)| core::iter::repeat(y).zip(row.iter().enumerate()).map(|(y, (x, c))| (y, x, c))).find_map(|(y, x, c)| (c == &Cell::Sourc).then_some((x, y))).unwrap(); - println!("Source {:?}", source); + let nodes: Vec<(usize, usize)> = grid.iter().enumerate().flat_map(|(y, row)| { + core::iter::repeat(y).zip(row.iter().enumerate().filter(|(_, c)| c != &&Cell::Empty)).map(|(y, (x, c))| (x, y)) + }).chain((0..width).zip(core::iter::repeat(height))).collect(); + println!("Nodes: {:?}", nodes.len()); + let node_map: HashMap<(usize, usize), usize> = nodes.iter().copied().enumerate().map(|(idx, v)| (v, idx)).collect(); - let mut splits = 0; - let mut queue: Vec<(usize, usize)> = vec![(source.0, source.1+1)]; - while let Some((x, mut y)) = queue.pop() { - if grid[y][x] != Cell::Empty { - continue; - } + let mut adj_matrix = DMatrix::from_element(nodes.len(), nodes.len(), 0); - while grid.get(y).map(|r| &r[x]) == Some(&Cell::Empty) { - // println!("({}, {})", x, y); + for (sx, sy) in nodes.iter().copied() { + match grid.get(sy).map(|r| &r[sx]) { + Some(Cell::Empty) | Some(Cell::TBeam) => unreachable!(), + Some(Cell::Sourc) => { + let x = sx; + let mut y = sy+1; + while grid.get(y).map(|r| &r[x]) == Some(&Cell::Empty) { + y += 1; + } - grid[y][x] = Cell::TBeam; - y += 1; - } + let s_idx = node_map.get(&(sx, sy)).unwrap(); + let t_idx = node_map.get(&(x, y)).unwrap(); - match grid.get(y).map(|r| &r[x]) { - None => {} - Some(Cell::Empty) => unreachable!(), - Some(Cell::Sourc) => unreachable!(), + adj_matrix[(*s_idx, *t_idx)] = 1; + } Some(Cell::Split) => { - // println!("Split"); - splits += 1; + for x in [sx-1, sx+1] { + let mut y = sy+1; + while grid.get(y).map(|r| &r[x]) == Some(&Cell::Empty) { + y += 1; + } - if let Some(nx) = x.checked_sub(1) { - queue.push((nx, y)); - } - if x+1 < grid[y].len() { - queue.push((x+1, y)); + let s_idx = node_map.get(&(sx, sy)).unwrap(); + let t_idx = node_map.get(&(x, y)).unwrap(); + + adj_matrix[(*s_idx, *t_idx)] = 1; } } - Some(Cell::TBeam) => { - println!("Beam"); - } + None => {} }; } - println!("Splits: {:?}", splits); + let source = nodes.iter().copied().find(|(x, y)| matches!(grid.get(*y).map(|r| &r[*x]), Some(Cell::Sourc))).unwrap(); + println!("Source: {:?}", source); + + // println!("{}", adj_matrix); + + let mut routes = 0; + let mut result_matrix = DMatrix::identity(nodes.len(), nodes.len()); + for i in 1..height { + result_matrix *= &adj_matrix; + + let versions = (0..width).map(|x| { + let s_idx = node_map.get(&source).unwrap(); + let t_idx = node_map.get(&(x, height)).unwrap(); + + let routes = result_matrix[(*s_idx, *t_idx)]; + + routes + }).sum::(); + println!("[{}] Routes {}", i, versions); + + routes += versions; + } + + println!("Total Routes: {:?}", routes); }