day(08): address DRY
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
e419087f1c
commit
7b364e35a3
1 changed files with 51 additions and 52 deletions
103
src/bin/day08.rs
103
src/bin/day08.rs
|
@ -10,44 +10,41 @@ use tracing_subscriber::EnvFilter;
|
|||
type Input = Vec<Vec<i8>>;
|
||||
type Output = usize;
|
||||
|
||||
type Position = Vector2D<usize>;
|
||||
type Visited = BTreeSet<Position>;
|
||||
|
||||
fn count_in(trees: &Input, counted: &mut BTreeSet<(usize, usize)>, swap: bool) {
|
||||
fn folder(
|
||||
trees: &Input,
|
||||
counted: &mut BTreeSet<(usize, usize)>,
|
||||
mut x: usize,
|
||||
mut y: usize,
|
||||
swap: bool,
|
||||
tallest: i8,
|
||||
) -> i8 {
|
||||
if swap {
|
||||
(x, y) = (y, x);
|
||||
}
|
||||
|
||||
if trees[y][x] > tallest {
|
||||
counted.insert((x, y));
|
||||
}
|
||||
|
||||
max(tallest, trees[y][x])
|
||||
}
|
||||
|
||||
(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()).rfold(-1, |tallest, x| folder(trees, counted, x, y, swap, tallest));
|
||||
})
|
||||
}
|
||||
|
||||
fn count_in_rows(trees: &Input, counted: &mut BTreeSet<(usize, usize)>) {
|
||||
trees.iter().enumerate().for_each(|(y, row)| {
|
||||
row.iter().enumerate().fold(-1, |tallest, (x, tree)| {
|
||||
if *tree > tallest {
|
||||
counted.insert((x, y));
|
||||
}
|
||||
|
||||
max(*tree, tallest)
|
||||
});
|
||||
|
||||
row.iter().enumerate().rfold(-1, |tallest, (x, tree)| {
|
||||
if *tree > tallest {
|
||||
counted.insert((x, y));
|
||||
}
|
||||
|
||||
max(*tree, tallest)
|
||||
});
|
||||
});
|
||||
count_in(trees, counted, false)
|
||||
}
|
||||
|
||||
fn count_in_columns(trees: &Input, counted: &mut BTreeSet<(usize, usize)>) {
|
||||
(0..trees[0].len()).for_each(|x| {
|
||||
(0..trees.len()).fold(-1, |tallest, y| {
|
||||
if trees[y][x] > tallest {
|
||||
counted.insert((x, y));
|
||||
}
|
||||
|
||||
max(tallest, trees[y][x])
|
||||
});
|
||||
|
||||
(0..trees.len()).rev().fold(-1, |tallest, y| {
|
||||
if trees[y][x] > tallest {
|
||||
counted.insert((x, y));
|
||||
}
|
||||
|
||||
max(tallest, trees[y][x])
|
||||
});
|
||||
});
|
||||
count_in(trees, counted, true)
|
||||
}
|
||||
|
||||
fn part_1(input: &Input) -> Output {
|
||||
|
@ -63,27 +60,29 @@ fn in_range(trees: &Input, x: i32, y: i32) -> bool {
|
|||
y >= 0 && y < trees.len() as i32 && x >= 0 && x < trees[y as usize].len() as i32
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
while in_range(trees, x + d * dx, y + d * dy) {
|
||||
visible += 1;
|
||||
|
||||
if trees[(y + d * dy) as usize][(x + d * dx) as usize] >= max_height {
|
||||
break;
|
||||
}
|
||||
|
||||
d += 1;
|
||||
}
|
||||
|
||||
visible as usize
|
||||
}
|
||||
|
||||
fn compute_scenic_score(trees: &Input, x: i32, y: i32) -> usize {
|
||||
vec![(0, 1), (1, 0), (0, -1), (-1, 0)]
|
||||
.iter()
|
||||
.map(|&(dx, dy)| {
|
||||
let max_height = trees[y as usize][x as usize];
|
||||
let mut d = 1;
|
||||
|
||||
let mut visible = 0;
|
||||
|
||||
while in_range(trees, x + d * dx, y + d * dy) {
|
||||
visible += 1;
|
||||
|
||||
if trees[(y + d * dy) as usize][(x + d * dx) as usize] >= max_height {
|
||||
break;
|
||||
}
|
||||
|
||||
d += 1;
|
||||
}
|
||||
|
||||
visible as usize
|
||||
})
|
||||
.map(|&(dx, dy)| count_visible(trees, x, y, dx, dy))
|
||||
.product()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue