1
0
Fork 0

vector2d: Implement ‹Index› and ‹IndexMut› traits

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2023-01-03 22:10:26 +01:00
parent cdd4087cd6
commit 9aa15bbf6f
Signed by: mfocko
GPG key ID: 7C47D46246790496
3 changed files with 58 additions and 41 deletions

View file

@ -23,11 +23,11 @@ fn count_in(trees: &Input, counted: &mut Visited, swap: bool) {
pos = pos.swap(); pos = pos.swap();
} }
if *index(trees, &pos) > tallest { if trees[pos] > tallest {
counted.insert(pos); counted.insert(pos);
} }
max(tallest, *index(trees, &pos)) max(tallest, trees[pos])
} }
(0..trees.len()).for_each(|y| { (0..trees.len()).for_each(|y| {
@ -49,14 +49,14 @@ fn count_in_columns(trees: &Input, counted: &mut Visited) {
} }
fn count_visible(trees: &Input, position: SignedPosition, diff: SignedPosition) -> usize { fn count_visible(trees: &Input, position: SignedPosition, diff: SignedPosition) -> usize {
let max_height = *index(trees, &position); let max_height = trees[position];
let mut visible = 0; let mut visible = 0;
let mut d = 1; let mut d = 1;
while in_range(trees, &(position + diff * d)) { while in_range(trees, &(position + diff * d)) {
visible += 1; visible += 1;
if *index(trees, &(position + diff * d)) >= max_height { if trees[position + diff * d] >= max_height {
break; break;
} }
@ -104,7 +104,8 @@ impl Solution<Input, Output> for Day08 {
fn part_2(input: &Input) -> Output { fn part_2(input: &Input) -> Output {
(0..input.len()) (0..input.len())
.flat_map(|y| { .flat_map(|y| {
(0..input[y].len()).map(move |x| compute_scenic_score(input, x as isize, y as isize)) (0..input[y].len())
.map(move |x| compute_scenic_score(input, x as isize, y as isize))
}) })
.max() .max()
.unwrap() .unwrap()

View file

@ -103,7 +103,7 @@ impl Solution<Input, Output> for Day12 {
fn part_1(input: &Input) -> Output { fn part_1(input: &Input) -> Output {
fn has_edge(graph: &[Vec<char>], from: &Position, to: &Position) -> bool { fn has_edge(graph: &[Vec<char>], from: &Position, to: &Position) -> bool {
get_elevation(*index(graph, to)) - get_elevation(*index(graph, from)) <= 1 get_elevation(graph[*to]) - get_elevation(graph[*from]) <= 1
} }
let (start, target) = (find_start(input), find_target(input)); let (start, target) = (find_start(input), find_target(input));
@ -116,11 +116,11 @@ impl Solution<Input, Output> for Day12 {
fn part_2(input: &Input) -> Output { fn part_2(input: &Input) -> Output {
fn has_edge(graph: &[Vec<char>], from: &Position, to: &Position) -> bool { fn has_edge(graph: &[Vec<char>], from: &Position, to: &Position) -> bool {
(get_elevation(*index(graph, from)) - get_elevation(*index(graph, to))) <= 1 (get_elevation(graph[*from]) - get_elevation(graph[*to])) <= 1
} }
fn is_target(graph: &[Vec<char>], vertex: &Position) -> bool { fn is_target(graph: &[Vec<char>], vertex: &Position) -> bool {
get_elevation(*index(graph, vertex)) == 0 get_elevation(graph[*vertex]) == 0
} }
let start = find_target(input); let start = find_target(input);

View file

@ -1,4 +1,5 @@
use std::cmp::Eq; use std::cmp::Eq;
use std::collections::VecDeque;
use std::fmt::Debug; use std::fmt::Debug;
use std::hash::Hash; use std::hash::Hash;
use std::ops::{Add, Index, IndexMut, Mul, Sub}; use std::ops::{Add, Index, IndexMut, Mul, Sub};
@ -23,27 +24,42 @@ impl<T> Vector2D<T> {
} }
} }
pub fn index<'a, C, I>(v: &'a [C], idx: &Vector2D<I>) -> &'a C::Output macro_rules! generate_indices {
($container:ty) => {
impl<I, C> Index<Vector2D<I>> for $container
where where
I: Copy, I: Copy + TryInto<usize>,
<I as TryInto<usize>>::Error: Debug,
C: Index<usize>, C: Index<usize>,
usize: TryFrom<I>,
<usize as TryFrom<I>>::Error: Debug,
{ {
let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap()); type Output = C::Output;
&v[y][x]
fn index(&self, index: Vector2D<I>) -> &Self::Output {
let (x, y): (usize, usize) =
(index.x.try_into().unwrap(), index.y.try_into().unwrap());
&self[y][x]
}
} }
pub fn index_mut<'a, C, I>(v: &'a mut [C], idx: &Vector2D<I>) -> &'a mut C::Output impl<I, C> IndexMut<Vector2D<I>> for $container
where where
I: Copy, I: Copy + TryInto<usize>,
<I as TryInto<usize>>::Error: Debug,
C: IndexMut<usize>, C: IndexMut<usize>,
usize: TryFrom<I>,
<usize as TryFrom<I>>::Error: Debug,
{ {
let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap()); fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
&mut v[y][x] let (x, y): (usize, usize) =
(index.x.try_into().unwrap(), index.y.try_into().unwrap());
&mut self[y][x]
} }
}
};
}
generate_indices!(VecDeque<C>);
generate_indices!([C]);
generate_indices!(Vec<C>);
// generate_indices!([C; N], const N: usize);
pub fn in_range<I, C>(v: &[Vec<C>], idx: &Vector2D<I>) -> bool pub fn in_range<I, C>(v: &[Vec<C>], idx: &Vector2D<I>) -> bool
where where