rename neighbours to adjacent, add count impl for cardinal

This commit is contained in:
2025-12-04 17:28:53 -08:00
parent faa452149a
commit fa7f62cacf
2 changed files with 24 additions and 14 deletions

View File

@@ -10,7 +10,7 @@ fn parse(input: &str) -> Grid<u8> {
fn part1(input: &Grid<u8>) -> u64 { fn part1(input: &Grid<u8>) -> u64 {
(0..input.height() * input.width()) (0..input.height() * input.width())
.filter(|i| *input.get(&input.coord(*i as i64).unwrap()).unwrap() == b'@') .filter(|i| *input.get(&input.coord(*i as i64).unwrap()).unwrap() == b'@')
.map(|i| input.neighbours_count(&input.coord(i as i64).unwrap(), |c| *c == b'@')) .map(|i| input.adjacent_count(&input.coord(i as i64).unwrap(), |c| *c == b'@'))
.filter(|n| *n < 4) .filter(|n| *n < 4)
.count() as u64 .count() as u64
} }
@@ -24,7 +24,7 @@ fn part2(input: &Grid<u8>) -> u64 {
for i in 0..grid.width() * grid.height() { for i in 0..grid.width() * grid.height() {
let pos = grid.coord(i as i64).unwrap(); let pos = grid.coord(i as i64).unwrap();
if grid.get(&pos).is_some_and(|c| *c == b'@') if grid.get(&pos).is_some_and(|c| *c == b'@')
&& grid.neighbours_count(&pos, |c| *c == b'@') < 4 && grid.adjacent_count(&pos, |c| *c == b'@') < 4
{ {
// remove the roll // remove the roll
grid.set(&pos, b'.'); grid.set(&pos, b'.');

View File

@@ -8,7 +8,7 @@ use std::{
}; };
/// NW, N, NE, W, E, SW, S, SE /// NW, N, NE, W, E, SW, S, SE
const ADJACENT_OFFSETS: [&(i64, i64); 8] = [ pub const ADJACENT_OFFSETS: [&(i64, i64); 8] = [
&(-1, -1), &(-1, -1),
&(0, -1), &(0, -1),
&(1, -1), &(1, -1),
@@ -20,14 +20,20 @@ const ADJACENT_OFFSETS: [&(i64, i64); 8] = [
]; ];
/// NESW /// NESW
const CARDINAL_OFFSETS: [&(i64, i64); 4] = [&(0, -1), &(-1, 0), &(1, 0), &(0, 1)]; pub const CARDINAL_OFFSETS: [&(i64, i64); 4] = [&(0, -1), &(-1, 0), &(1, 0), &(0, 1)];
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Coord2d { pub struct Coord2d {
pub x: i64, pub x: i64,
pub y: i64, pub y: i64,
} }
impl Debug for Coord2d {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("({}, {})", self.x, self.y))
}
}
pub trait AsCoord2d { pub trait AsCoord2d {
fn to_coord(self) -> Coord2d; fn to_coord(self) -> Coord2d;
fn x(&self) -> i64; fn x(&self) -> i64;
@@ -402,7 +408,7 @@ impl<T: Clone + Eq + PartialEq + Debug> Grid<T> {
) )
} }
/// Get all of the coordinates having value `needle` /// Get all of the coordinates having value `needle`
pub fn find_all<'a>(&'a self, needle: &'a T) -> impl Iterator<Item = Coord2d> + 'a { pub fn find_all<'a>(&'a self, needle: &'a T) -> impl DoubleEndedIterator<Item = Coord2d> + 'a {
self.data self.data
.iter() .iter()
.enumerate() .enumerate()
@@ -430,19 +436,23 @@ impl<T: Clone + Eq + PartialEq + Debug> Grid<T> {
} }
/// Return the count of neighbours (8 directions) matching predicate p /// Return the count of neighbours (8 directions) matching predicate p
pub fn neighbours_count<C: AsCoord2d + Copy, P>(&self, c: &C, mut p: P) -> usize pub fn adjacent_count<C: AsCoord2d + Copy, P>(&self, c: &C, mut p: P) -> usize
where where
P: FnMut(&T) -> bool, P: FnMut(&T) -> bool,
{ {
ADJACENT_OFFSETS self.adjacent_iter(c).filter(|i| p(i.value)).count()
.iter() }
.map(|d| c.to_coord() + *d)
.filter(|c| self.get(c).is_some_and(&mut p)) /// Return the count of cardinal neighbours (4 directions) matching predicate p
.count() pub fn cardinal_count<C: AsCoord2d + Copy, P>(&self, c: &C, mut p: P) -> usize
where
P: FnMut(&T) -> bool,
{
self.cardinal_iter(c).filter(|i| p(i.value)).count()
} }
/// Return an iterator over the 8 neighbours of c. The iterator skips neighbouring positions outside of the grid. /// Return an iterator over the 8 neighbours of c. The iterator skips neighbouring positions outside of the grid.
pub fn neighbours_iter<C: AsCoord2d + Copy>(&self, c: &C) -> OffsetsIter<T> { pub fn adjacent_iter<C: AsCoord2d + Copy>(&self, c: &C) -> OffsetsIter<T> {
OffsetsIter { OffsetsIter {
grid: self, grid: self,
origin: c.to_coord(), origin: c.to_coord(),
@@ -636,7 +646,7 @@ FBCG";
fn neighbours_iter() { fn neighbours_iter() {
let grid = unchecked_load(); let grid = unchecked_load();
assert_eq!( assert_eq!(
grid.neighbours_iter(&(0, 1)).collect::<Vec<_>>(), grid.adjacent_iter(&(0, 1)).collect::<Vec<_>>(),
[ [
Item { Item {
pos: Coord2d { x: 0, y: 0 }, pos: Coord2d { x: 0, y: 0 },