Extract some grid functionality into trait

This commit is contained in:
kageru 2021-12-11 22:54:57 +01:00
parent e668c96185
commit 8ccab04d6f
Signed by: kageru
GPG Key ID: 8282A2BEA4ADA3D2
4 changed files with 30 additions and 20 deletions

View File

@ -4,7 +4,7 @@ use std::collections::HashSet;
use aoc2021::common::*;
const DAY: usize = 09;
const DAY: usize = 9;
type Parsed = Vec<Vec<u8>>;
fn parse_input(raw: &str) -> Parsed {

View File

@ -3,15 +3,15 @@
extern crate test;
use aoc2021::{
common::*,
grid::{Grid, PositionND},
grid::{Grid, HashGrid, PositionND},
};
const DAY: usize = 11;
const ROUNDS: usize = 100;
type Parsed = Grid<u8, 2>;
type Parsed = HashGrid<u8, 2>;
fn parse_input(raw: &str) -> Parsed {
Grid::<u8, 2>::from_bytes_2d(raw, |b: u8| b - b'0')
HashGrid::<u8, 2>::from_bytes_2d(raw, |b: u8| b - b'0')
}
fn part1(parsed: &Parsed) -> usize {
@ -80,5 +80,5 @@ mod tests {
test!(part2() == 195);
bench!(part1() == 1741);
bench!(part2() == 440);
bench_input!(Grid::len => 100);
bench_input!(HashGrid::len => 100);
}

View File

@ -2,40 +2,50 @@ pub mod cell;
pub mod direction;
pub mod position;
pub use direction::*;
pub use position::*;
use itertools::join;
pub use position::*;
use std::{collections::HashMap, fmt::Display, hash::BuildHasher};
#[allow(clippy::len_without_is_empty)] // I mainly have this for assertions in benchmarks
pub trait Grid<T, const D: usize> {
fn get(&self, pos: &PositionND<D>) -> Option<&T>;
fn insert<Pos: Into<PositionND<D>>>(&mut self, pos: Pos, element: T);
fn len(&self) -> usize;
}
#[derive(Debug, Clone, PartialEq)]
pub struct Grid<T: Default, const D: usize> {
pub struct HashGrid<T: Default, const D: usize> {
pub fields: HashMap<PositionND<D>, T>,
}
impl<T: Default + Copy, const D: usize> Grid<T, D> {
pub fn get(&self, pos: &PositionND<D>) -> T {
self.fields.get(pos).copied().unwrap_or_else(T::default)
impl<T: Default, const D: usize> Grid<T, D> for HashGrid<T, D> {
fn get(&self, pos: &PositionND<D>) -> Option<&T> {
self.fields.get(pos)
}
pub fn insert<Pos: Into<PositionND<D>>>(&mut self, pos: Pos, t: T) {
fn insert<Pos: Into<PositionND<D>>>(&mut self, pos: Pos, t: T) {
self.fields.insert(pos.into(), t);
}
pub fn from_bytes_2d<F: FnMut(u8) -> T + Copy>(raw: &str, mut f: F) -> Grid<T, 2> {
fn len(&self) -> usize {
self.fields.len()
}
}
impl<T: Default + Copy, const D: usize> HashGrid<T, D> {
pub fn from_bytes_2d<F: FnMut(u8) -> T + Copy>(raw: &str, mut f: F) -> HashGrid<T, 2> {
raw.lines()
.enumerate()
.flat_map(move |(y, l)| l.bytes().enumerate().map(move |(x, c)| (PositionND { points: [x as i64, y as i64] }, f(c))))
.collect()
}
pub fn len(&self) -> usize {
self.fields.len()
}
}
impl<T: Default, const D: usize> std::iter::FromIterator<(PositionND<D>, T)> for Grid<T, D> {
impl<T: Default, const D: usize> std::iter::FromIterator<(PositionND<D>, T)> for HashGrid<T, D> {
fn from_iter<I: IntoIterator<Item = (PositionND<D>, T)>>(iter: I) -> Self {
Grid { fields: iter.into_iter().collect() }
HashGrid { fields: iter.into_iter().collect() }
}
}
@ -46,7 +56,6 @@ struct Boundaries {
y_max: i64,
}
#[rustfmt::skip]
fn get_boundaries(input: &[&PositionND<2>]) -> Boundaries {
let x_min = input.iter().min_by_key(|k| k.points[0]).map(|p| p.points[0]).unwrap_or(0);
let x_max = input.iter().max_by_key(|k| k.points[0]).map(|p| p.points[0]).unwrap_or(0);

View File

@ -49,6 +49,7 @@ impl<const DIMS: usize> PositionND<DIMS> {
pub fn from_padded(slice: &[i64]) -> PositionND<DIMS> {
let mut points = [0; DIMS];
#[allow(clippy::manual_memcpy)]
for i in 0..(DIMS.min(slice.len())) {
points[i] = slice[i];
}