Files
aoc/2025/07.rs
2026-01-09 19:49:23 +01:00

101 lines
3.0 KiB
Rust

---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)]
enum Cell {
Empty,
Split,
Sourc,
TBeam,
}
fn main() {
let mut grid: Vec<_> = CONTENT.lines().map(|l| l.trim()).filter(|l| !l.is_empty()).map(|l| {
l.chars().map(|c| match c {
'.' => Cell::Empty,
'S' => Cell::Sourc,
'^' => Cell::Split,
other => unreachable!("Unexpected Input {:?}", other),
}).collect::<Vec<_>>()
}).collect();
let height = grid.len();
let width = grid[0].len();
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 adj_matrix = DMatrix::from_element(nodes.len(), nodes.len(), 0);
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;
}
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::Split) => {
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;
}
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;
}
}
None => {}
};
}
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::<usize>();
println!("[{}] Routes {}", i, versions);
routes += versions;
}
println!("Total Routes: {:?}", routes);
}