advent_of_code/year2022/
day08.rs1use crate::input::Input;
2
3pub fn solve(input: &Input) -> Result<usize, String> {
4 let grid = input
5 .text
6 .bytes()
7 .filter(u8::is_ascii_digit)
8 .map(|b| b - b'0')
9 .collect::<Vec<_>>();
10
11 let grid_size = (grid.len() as f64).sqrt() as usize;
12 if grid_size * grid_size != grid.len() {
13 return Err("Non-rectangular grid".to_string());
14 }
15
16 let mut num_visible = 0;
17 let mut best_scenic_score = 0;
18
19 'start: for start in 0..grid.len() {
20 let mut scenic_score = 1;
21 'stride: for (stride, steps) in [
22 (-1, start % grid_size),
23 (1, grid_size - start % grid_size - 1),
24 (-(grid_size as i32), start / grid_size),
25 ((grid_size as i32), grid_size - start / grid_size - 1),
26 ] {
27 let mut position = start as i32;
28 let start_height = grid[start];
29
30 for step in 1..=steps {
31 position += stride;
32 let height_at_position = grid[position as usize];
33 if height_at_position >= start_height {
34 scenic_score *= step;
35 continue 'stride;
36 }
37 }
38
39 if input.is_part_one() {
40 num_visible += 1;
41 continue 'start;
42 }
43 scenic_score *= steps;
44 }
45
46 best_scenic_score = best_scenic_score.max(scenic_score);
47 }
48
49 Ok(input.part_values(num_visible, best_scenic_score))
50}
51
52#[test]
53pub fn tests() {
54 use crate::input::{test_part_one, test_part_two};
55
56 let test_input = "30373
5725512
5865332
5933549
6035390";
61 test_part_one!(test_input => 21);
62 test_part_two!(test_input => 8);
63
64 let real_input = include_str!("day08_input.txt");
65 test_part_one!(real_input => 1_672);
66 test_part_two!(real_input => 327_180);
67}