From 7b364e35a33ec4e8f87064123c3a7a6f36c1b201 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Thu, 8 Dec 2022 12:50:14 +0100 Subject: [PATCH] day(08): address DRY Signed-off-by: Matej Focko --- src/bin/day08.rs | 103 +++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 52 deletions(-) diff --git a/src/bin/day08.rs b/src/bin/day08.rs index a1fe4dc..deeab84 100644 --- a/src/bin/day08.rs +++ b/src/bin/day08.rs @@ -10,44 +10,41 @@ use tracing_subscriber::EnvFilter; type Input = Vec>; type Output = usize; +type Position = Vector2D; +type Visited = BTreeSet; + +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() }