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;
} }
@ -83,31 +83,32 @@ struct Day08;
impl Solution<Input, Output> for Day08 { impl Solution<Input, Output> for Day08 {
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input { fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
file_to_string(pathname) file_to_string(pathname)
.lines() .lines()
.map(|line| { .map(|line| {
line.chars() line.chars()
.map(|c| c.to_digit(10).unwrap() as i8) .map(|c| c.to_digit(10).unwrap() as i8)
.collect_vec() .collect_vec()
}) })
.collect_vec() .collect_vec()
} }
fn part_1(input: &Input) -> Output { fn part_1(input: &Input) -> Output {
let mut counted = Visited::new(); let mut counted = Visited::new();
count_in_rows(input, &mut counted); count_in_rows(input, &mut counted);
count_in_columns(input, &mut counted); count_in_columns(input, &mut counted);
counted.len() counted.len()
} }
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() })
.unwrap() .max()
.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 {
where ($container:ty) => {
I: Copy, impl<I, C> Index<Vector2D<I>> for $container
C: Index<usize>, where
usize: TryFrom<I>, I: Copy + TryInto<usize>,
<usize as TryFrom<I>>::Error: Debug, <I as TryInto<usize>>::Error: Debug,
{ C: Index<usize>,
let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap()); {
&v[y][x] type Output = C::Output;
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]
}
}
impl<I, C> IndexMut<Vector2D<I>> for $container
where
I: Copy + TryInto<usize>,
<I as TryInto<usize>>::Error: Debug,
C: IndexMut<usize>,
{
fn index_mut(&mut self, index: Vector2D<I>) -> &mut Self::Output {
let (x, y): (usize, usize) =
(index.x.try_into().unwrap(), index.y.try_into().unwrap());
&mut self[y][x]
}
}
};
} }
pub fn index_mut<'a, C, I>(v: &'a mut [C], idx: &Vector2D<I>) -> &'a mut C::Output generate_indices!(VecDeque<C>);
where generate_indices!([C]);
I: Copy, generate_indices!(Vec<C>);
C: IndexMut<usize>, // generate_indices!([C; N], const N: 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());
&mut v[y][x]
}
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