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();
|
||||
}
|
||||
|
||||
if *index(trees, &pos) > tallest {
|
||||
if trees[pos] > tallest {
|
||||
counted.insert(pos);
|
||||
}
|
||||
|
||||
max(tallest, *index(trees, &pos))
|
||||
max(tallest, trees[pos])
|
||||
}
|
||||
|
||||
(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 {
|
||||
let max_height = *index(trees, &position);
|
||||
let max_height = trees[position];
|
||||
let mut visible = 0;
|
||||
|
||||
let mut d = 1;
|
||||
while in_range(trees, &(position + diff * d)) {
|
||||
visible += 1;
|
||||
|
||||
if *index(trees, &(position + diff * d)) >= max_height {
|
||||
if trees[position + diff * d] >= max_height {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -83,31 +83,32 @@ struct Day08;
|
|||
impl Solution<Input, Output> for Day08 {
|
||||
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
||||
file_to_string(pathname)
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.chars()
|
||||
.map(|c| c.to_digit(10).unwrap() as i8)
|
||||
.collect_vec()
|
||||
})
|
||||
.collect_vec()
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.chars()
|
||||
.map(|c| c.to_digit(10).unwrap() as i8)
|
||||
.collect_vec()
|
||||
})
|
||||
.collect_vec()
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
let mut counted = Visited::new();
|
||||
|
||||
count_in_rows(input, &mut counted);
|
||||
count_in_columns(input, &mut counted);
|
||||
count_in_rows(input, &mut counted);
|
||||
count_in_columns(input, &mut counted);
|
||||
|
||||
counted.len()
|
||||
counted.len()
|
||||
}
|
||||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
(0..input.len())
|
||||
.flat_map(|y| {
|
||||
(0..input[y].len()).map(move |x| compute_scenic_score(input, x as isize, y as isize))
|
||||
})
|
||||
.max()
|
||||
.unwrap()
|
||||
.flat_map(|y| {
|
||||
(0..input[y].len())
|
||||
.map(move |x| compute_scenic_score(input, x as isize, y as isize))
|
||||
})
|
||||
.max()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ impl Solution<Input, Output> for Day12 {
|
|||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
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));
|
||||
|
@ -116,11 +116,11 @@ impl Solution<Input, Output> for Day12 {
|
|||
|
||||
fn part_2(input: &Input) -> Output {
|
||||
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 {
|
||||
get_elevation(*index(graph, vertex)) == 0
|
||||
get_elevation(graph[*vertex]) == 0
|
||||
}
|
||||
|
||||
let start = find_target(input);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::cmp::Eq;
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
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
|
||||
where
|
||||
I: Copy,
|
||||
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());
|
||||
&v[y][x]
|
||||
macro_rules! generate_indices {
|
||||
($container:ty) => {
|
||||
impl<I, C> Index<Vector2D<I>> for $container
|
||||
where
|
||||
I: Copy + TryInto<usize>,
|
||||
<I as TryInto<usize>>::Error: Debug,
|
||||
C: Index<usize>,
|
||||
{
|
||||
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
|
||||
where
|
||||
I: Copy,
|
||||
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());
|
||||
&mut v[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
|
||||
where
|
||||
|
|
Loading…
Reference in a new issue