diff options
| author | mhsn <mail@mhsn.net> | 2026-03-18 21:48:13 +0000 |
|---|---|---|
| committer | mhsn <mail@mhsn.net> | 2026-03-18 21:48:13 +0000 |
| commit | 86bac31392a76da84817eec020d2b84d099b3cc1 (patch) | |
| tree | e2ee52db59b86b914d5b4bcceb19c9b5d899fff4 /aoc/2025/04 | |
| parent | 62fe361fc42dea75deaf7ac31c0ba6ba80e26a9c (diff) | |
| download | puzzles-master.tar.gz puzzles-master.zip | |
Diffstat (limited to 'aoc/2025/04')
| -rwxr-xr-x | aoc/2025/04/python.py | 36 | ||||
| -rw-r--r-- | aoc/2025/04/rust/Cargo.lock | 7 | ||||
| -rw-r--r-- | aoc/2025/04/rust/Cargo.toml | 6 | ||||
| -rw-r--r-- | aoc/2025/04/rust/src/main.rs | 66 |
4 files changed, 115 insertions, 0 deletions
diff --git a/aoc/2025/04/python.py b/aoc/2025/04/python.py new file mode 100755 index 0000000..844c38e --- /dev/null +++ b/aoc/2025/04/python.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 + +from fileinput import input + +g = { + complex(x, y): ch + for y, line in enumerate(input()) + for x, ch in enumerate(line.strip()) +} + + +def accessible(): + return { + p + for p, x in g.items() + if x == "@" + and sum( + 1 + for dx in (-1, 0, 1) + for dy in (-1j, 0j, 1j) + if dx + dy != 0 and g.get(p + dx + dy, ".") == "@" + ) + < 4 + } + + +silver = len(accessible()) +gold = 0 + +while rem := accessible(): + gold += len(rem) + for gone in rem: + g.pop(gone) + +print("silver:", silver) +print("gold:", gold) 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))) +} |
