rename neighbours to adjacent, add count impl for cardinal
This commit is contained in:
@@ -10,7 +10,7 @@ fn parse(input: &str) -> Grid<u8> {
|
||||
fn part1(input: &Grid<u8>) -> u64 {
|
||||
(0..input.height() * input.width())
|
||||
.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)
|
||||
.count() as u64
|
||||
}
|
||||
@@ -24,7 +24,7 @@ fn part2(input: &Grid<u8>) -> u64 {
|
||||
for i in 0..grid.width() * grid.height() {
|
||||
let pos = grid.coord(i as i64).unwrap();
|
||||
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
|
||||
grid.set(&pos, b'.');
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::{
|
||||
};
|
||||
|
||||
/// NW, N, NE, W, E, SW, S, SE
|
||||
const ADJACENT_OFFSETS: [&(i64, i64); 8] = [
|
||||
pub const ADJACENT_OFFSETS: [&(i64, i64); 8] = [
|
||||
&(-1, -1),
|
||||
&(0, -1),
|
||||
&(1, -1),
|
||||
@@ -20,14 +20,20 @@ const ADJACENT_OFFSETS: [&(i64, i64); 8] = [
|
||||
];
|
||||
|
||||
/// 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 x: 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 {
|
||||
fn to_coord(self) -> Coord2d;
|
||||
fn x(&self) -> i64;
|
||||
@@ -402,7 +408,7 @@ impl<T: Clone + Eq + PartialEq + Debug> Grid<T> {
|
||||
)
|
||||
}
|
||||
/// 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
|
||||
.iter()
|
||||
.enumerate()
|
||||
@@ -430,19 +436,23 @@ impl<T: Clone + Eq + PartialEq + Debug> Grid<T> {
|
||||
}
|
||||
|
||||
/// 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
|
||||
P: FnMut(&T) -> bool,
|
||||
{
|
||||
ADJACENT_OFFSETS
|
||||
.iter()
|
||||
.map(|d| c.to_coord() + *d)
|
||||
.filter(|c| self.get(c).is_some_and(&mut p))
|
||||
.count()
|
||||
self.adjacent_iter(c).filter(|i| p(i.value)).count()
|
||||
}
|
||||
|
||||
/// Return the count of cardinal neighbours (4 directions) matching predicate p
|
||||
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.
|
||||
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 {
|
||||
grid: self,
|
||||
origin: c.to_coord(),
|
||||
@@ -636,7 +646,7 @@ FBCG";
|
||||
fn neighbours_iter() {
|
||||
let grid = unchecked_load();
|
||||
assert_eq!(
|
||||
grid.neighbours_iter(&(0, 1)).collect::<Vec<_>>(),
|
||||
grid.adjacent_iter(&(0, 1)).collect::<Vec<_>>(),
|
||||
[
|
||||
Item {
|
||||
pos: Coord2d { x: 0, y: 0 },
|
||||
|
||||
Reference in New Issue
Block a user