summaryrefslogtreecommitdiff
path: root/aoc/2025/04/rust
diff options
context:
space:
mode:
authormhsn <mail@mhsn.net>2026-03-18 21:48:13 +0000
committermhsn <mail@mhsn.net>2026-03-18 21:48:13 +0000
commit86bac31392a76da84817eec020d2b84d099b3cc1 (patch)
treee2ee52db59b86b914d5b4bcceb19c9b5d899fff4 /aoc/2025/04/rust
parent62fe361fc42dea75deaf7ac31c0ba6ba80e26a9c (diff)
downloadpuzzles-86bac31392a76da84817eec020d2b84d099b3cc1.tar.gz
puzzles-86bac31392a76da84817eec020d2b84d099b3cc1.zip
add other challenges supportHEADmaster
Diffstat (limited to 'aoc/2025/04/rust')
-rw-r--r--aoc/2025/04/rust/Cargo.lock7
-rw-r--r--aoc/2025/04/rust/Cargo.toml6
-rw-r--r--aoc/2025/04/rust/src/main.rs66
3 files changed, 79 insertions, 0 deletions
diff --git a/aoc/2025/04/rust/Cargo.lock b/aoc/2025/04/rust/Cargo.lock
new file mode 100644
index 0000000..ac79b17
--- /dev/null
+++ b/aoc/2025/04/rust/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "puzzle"
+version = "0.1.0"
diff --git a/aoc/2025/04/rust/Cargo.toml b/aoc/2025/04/rust/Cargo.toml
new file mode 100644
index 0000000..26e4e77
--- /dev/null
+++ b/aoc/2025/04/rust/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "puzzle"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
diff --git a/aoc/2025/04/rust/src/main.rs b/aoc/2025/04/rust/src/main.rs
new file mode 100644
index 0000000..3b13140
--- /dev/null
+++ b/aoc/2025/04/rust/src/main.rs
@@ -0,0 +1,66 @@
+use std::{collections::VecDeque, io};
+
+fn main() {
+ let mut grid: Vec<Vec<Option<usize>>> = io::stdin()
+ .lines()
+ .flatten()
+ .map(|line| line.chars().map(|ch| (ch == '@').then_some(0)).collect())
+ .collect();
+
+ // 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))
+ }
+ }
+ });
+ }
+
+ 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)))
+}