day(08): refactor with ‹Vector2D›
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
fa7cc5c241
commit
4b97615e6a
1 changed files with 31 additions and 26 deletions
|
@ -10,45 +10,49 @@ use tracing_subscriber::EnvFilter;
|
||||||
type Input = Vec<Vec<i8>>;
|
type Input = Vec<Vec<i8>>;
|
||||||
type Output = usize;
|
type Output = usize;
|
||||||
|
|
||||||
|
type SignedPosition = Vector2D<isize>;
|
||||||
type Position = Vector2D<usize>;
|
type Position = Vector2D<usize>;
|
||||||
type Visited = BTreeSet<Position>;
|
type Visited = BTreeSet<Position>;
|
||||||
|
|
||||||
fn count_in(trees: &Input, counted: &mut BTreeSet<(usize, usize)>, swap: bool) {
|
fn count_in(trees: &Input, counted: &mut Visited, swap: bool) {
|
||||||
fn folder(
|
fn folder(
|
||||||
trees: &Input,
|
trees: &Input,
|
||||||
counted: &mut BTreeSet<(usize, usize)>,
|
counted: &mut Visited,
|
||||||
mut x: usize,
|
mut pos: Position,
|
||||||
mut y: usize,
|
|
||||||
swap: bool,
|
swap: bool,
|
||||||
tallest: i8,
|
tallest: i8,
|
||||||
) -> i8 {
|
) -> i8 {
|
||||||
if swap {
|
if swap {
|
||||||
(x, y) = (y, x);
|
pos = pos.swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if trees[y][x] > tallest {
|
if *index(trees, &pos) > tallest {
|
||||||
counted.insert((x, y));
|
counted.insert(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
max(tallest, trees[y][x])
|
max(tallest, *index(trees, &pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
(0..trees.len()).for_each(|y| {
|
(0..trees.len()).for_each(|y| {
|
||||||
(0..trees[y].len()).fold(-1, |tallest, x| folder(trees, counted, x, y, swap, tallest));
|
(0..trees[y].len()).fold(-1, |tallest, x| {
|
||||||
(0..trees[y].len()).rfold(-1, |tallest, x| folder(trees, counted, x, y, swap, tallest));
|
folder(trees, counted, Position::new(x, y), swap, tallest)
|
||||||
|
});
|
||||||
|
(0..trees[y].len()).rfold(-1, |tallest, x| {
|
||||||
|
folder(trees, counted, Position::new(x, y), swap, tallest)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count_in_rows(trees: &Input, counted: &mut BTreeSet<(usize, usize)>) {
|
fn count_in_rows(trees: &Input, counted: &mut Visited) {
|
||||||
count_in(trees, counted, false)
|
count_in(trees, counted, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn count_in_columns(trees: &Input, counted: &mut BTreeSet<(usize, usize)>) {
|
fn count_in_columns(trees: &Input, counted: &mut Visited) {
|
||||||
count_in(trees, counted, true)
|
count_in(trees, counted, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_1(input: &Input) -> Output {
|
fn part_1(input: &Input) -> Output {
|
||||||
let mut counted: BTreeSet<(usize, usize)> = BTreeSet::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);
|
||||||
|
@ -56,20 +60,15 @@ fn part_1(input: &Input) -> Output {
|
||||||
counted.len()
|
counted.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_range(trees: &Input, x: i32, y: i32) -> bool {
|
fn count_visible(trees: &Input, position: SignedPosition, diff: SignedPosition) -> usize {
|
||||||
y >= 0 && y < trees.len() as i32 && x >= 0 && x < trees[y as usize].len() as i32
|
let max_height = *index(trees, &position);
|
||||||
}
|
|
||||||
|
|
||||||
fn count_visible(trees: &Input, x: i32, y: i32, dx: i32, dy: i32) -> usize {
|
|
||||||
let max_height = trees[y as usize][x as usize];
|
|
||||||
let mut d = 1;
|
|
||||||
|
|
||||||
let mut visible = 0;
|
let mut visible = 0;
|
||||||
|
|
||||||
while in_range(trees, x + d * dx, y + d * dy) {
|
let mut d = 1;
|
||||||
|
while in_range(trees, &(position + diff * d)) {
|
||||||
visible += 1;
|
visible += 1;
|
||||||
|
|
||||||
if trees[(y + d * dy) as usize][(x + d * dx) as usize] >= max_height {
|
if *index(trees, &(position + diff * d)) >= max_height {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,17 +78,23 @@ fn count_visible(trees: &Input, x: i32, y: i32, dx: i32, dy: i32) -> usize {
|
||||||
visible as usize
|
visible as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_scenic_score(trees: &Input, x: i32, y: i32) -> usize {
|
fn compute_scenic_score(trees: &Input, x: isize, y: isize) -> usize {
|
||||||
vec![(0, 1), (1, 0), (0, -1), (-1, 0)]
|
vec![(0, 1), (1, 0), (0, -1), (-1, 0)]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(dx, dy)| count_visible(trees, x, y, dx, dy))
|
.map(|&(dx, dy)| {
|
||||||
|
count_visible(
|
||||||
|
trees,
|
||||||
|
SignedPosition::new(x, y),
|
||||||
|
SignedPosition::new(dx, dy),
|
||||||
|
)
|
||||||
|
})
|
||||||
.product()
|
.product()
|
||||||
}
|
}
|
||||||
|
|
||||||
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 i32, y as i32))
|
(0..input[y].len()).map(move |x| compute_scenic_score(input, x as isize, y as isize))
|
||||||
})
|
})
|
||||||
.max()
|
.max()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
Loading…
Reference in a new issue