summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormhsn <mail@mhsn.net>2026-01-10 10:56:15 +0000
committermhsn <mail@mhsn.net>2026-01-10 10:56:15 +0000
commitd906705b9bfc8038381816f03676a69cbf91bd84 (patch)
tree76c45544f40ce324ddf1252490aea4f6b68ecb80
parent4d3fc54257fd198439c376eaab6b4e558c91bdcb (diff)
downloadaoc-d906705b9bfc8038381816f03676a69cbf91bd84.tar.gz
aoc-d906705b9bfc8038381816f03676a69cbf91bd84.zip
25-04 rust finish
-rw-r--r--2025/04/rust/src/main.rs68
1 files changed, 51 insertions, 17 deletions
diff --git a/2025/04/rust/src/main.rs b/2025/04/rust/src/main.rs
index 5d703c5..3b13140 100644
--- a/2025/04/rust/src/main.rs
+++ b/2025/04/rust/src/main.rs
@@ -1,4 +1,4 @@
-use std::io;
+use std::{collections::VecDeque, io};
fn main() {
let mut grid: Vec<Vec<Option<usize>>> = io::stdin()
@@ -7,26 +7,60 @@ fn main() {
.map(|line| line.chars().map(|ch| (ch == '@').then_some(0)).collect())
.collect();
- for (y, row) in grid.iter().enumerate() {
- for (x, p) in row.iter().enumerate() {
- let Some(_) = p else {
- continue;
- };
-
- for nx in x.saturating_sub(1)..=(x + 1).min(row.len() - 1) {
- for ny in y.saturating_sub(1)..=(y + 1).min(grid.len() - 1) {
- // lol quadruple for loop (this makes me sad)
- if (x, y) == (nx, ny) {
- continue;
- }
- let mut h = grid.get(ny).and_then(|r| r.get(nx)).unwrap();
- }
+ // count neighbours
+ points(&grid)
+ .collect::<Vec<_>>()
+ .into_iter()
+ .for_each(|p @ (x, y)| {
+ let ns = neighbours(p, &grid).count();
+ if let Some(n) = grid[y][x].as_mut() {
+ *n = ns;
}
+ });
+
+ let mut stack = points(&grid)
+ .filter(|&(x, y)| grid[y][x].is_some_and(|n| n < 4))
+ .collect::<VecDeque<_>>();
+ let silver = stack.len();
+ let mut gold = 0;
+
+ while let Some(p @ (x, y)) = stack.pop_back() {
+ if grid[y][x].take().is_none() {
+ continue;
}
+ gold += 1;
+ // reduce neighbours' neighbour counts by 1
+ neighbours(p, &grid)
+ .collect::<Vec<_>>()
+ .into_iter()
+ .for_each(|(nx, ny)| {
+ if let Some(n) = grid[ny][nx].as_mut() {
+ *n -= 1;
+ if *n < 4 {
+ stack.push_back((nx, ny))
+ }
+ }
+ });
}
- let silver: u64 = 0;
- let gold: u64 = 0;
println!("silver: {silver}");
println!("gold: {gold}");
}
+
+fn neighbours<T>(
+ (x, y): (usize, usize),
+ grid: &Vec<Vec<Option<T>>>,
+) -> impl Iterator<Item = (usize, usize)> {
+ let xs = x.saturating_sub(1)..=(x + 1).min(grid.first().unwrap().len() - 1);
+ let ys = y.saturating_sub(1)..=(y + 1).min(grid.len() - 1);
+
+ xs.flat_map(move |nx| ys.clone().map(move |ny| (nx, ny)))
+ .filter(move |n| *n != (x, y))
+ .filter(|&(nx, ny)| grid.get(ny).and_then(|row| row.get(nx)).unwrap().is_some())
+}
+
+fn points<T>(grid: &Vec<Vec<T>>) -> impl Iterator<Item = (usize, usize)> {
+ let xs = 0..grid.first().unwrap().len();
+ let ys = 0..grid.len();
+ xs.flat_map(move |x| ys.clone().map(move |y| (x, y)))
+}