vector2d: Implement ‹Index› and ‹IndexMut› traits
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
cdd4087cd6
commit
9aa15bbf6f
3 changed files with 58 additions and 41 deletions
|
@ -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()
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
where
|
||||||
|
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,
|
type Output = C::Output;
|
||||||
{
|
|
||||||
let (x, y): (usize, usize) = (idx.x.try_into().unwrap(), idx.y.try_into().unwrap());
|
fn index(&self, index: Vector2D<I>) -> &Self::Output {
|
||||||
&v[y][x]
|
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
|
||||||
|
|
Loading…
Reference in a new issue