aboutsummaryrefslogtreecommitdiff
path: root/2022/src/day08.rs
blob: 514cb21fc76af491e87f5ea2a7e0ed84259c8f47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
mod utils;

use utils::read_input;

fn main() {
    let input = read_input();

    let mut grid: Vec<Vec<_>> = input
        .lines()
        .map(|x| {
            x.chars()
                .map(|x| (x.to_digit(10).unwrap() as u8, false))
                .collect()
        })
        .collect();
    in_all_directions!(check_vis_along_run, grid);

    println!(
        "Part 1: {}",
        grid.iter()
            .map(|x| x.iter().filter(|x| x.1).count())
            .sum::<usize>()
    );

    let mut grid: Vec<Vec<(u8, u32)>> = grid
        .into_iter()
        .map(|x| x.into_iter().map(|(x, _)| (x, 1)).collect())
        .collect();
    in_all_directions!(vis_score_along_run, grid);

    println!(
        "Part 2: {}",
        grid.iter()
            .map(|row| row.iter().map(|(_, vis)| vis).max().unwrap())
            .max()
            .unwrap()
    );
}

fn check_vis_along_run(
    mut run: impl Iterator<Item = (usize, usize)>,
    grid: &mut [Vec<(u8, bool)>],
) {
    let mut curr_height = {
        let (row_idx, col_idx) = run.next().unwrap();

        grid[row_idx][col_idx].1 = true;

        grid[row_idx][col_idx].0
    };
    for (row_idx, col_idx) in run {
        let height = grid[row_idx][col_idx].0;
        if height > curr_height {
            curr_height = height;
            grid[row_idx][col_idx].1 = true;
        }
    }
}

fn vis_score_along_run(run: impl Iterator<Item = (usize, usize)>, grid: &mut [Vec<(u8, u32)>]) {
    let mut next_values = [0; 10];
    for (row_idx, col_idx) in run {
        let height = grid[row_idx][col_idx].0;
        grid[row_idx][col_idx].1 *= next_values[height as usize];

        for (val, score) in next_values.iter_mut().enumerate() {
            *score = if *score == 0 || val > height as usize {
                *score + 1
            } else {
                1
            };
        }
    }
}

#[macro_use]
mod codegen {
    #[macro_export]
    macro_rules! in_all_directions {
        ($f:ident, $grid: ident) => {
            let grid_rows = $grid.len();
            let grid_cols = $grid[0].len();

            (0..grid_rows).for_each(|grid_row| {
                $f(
                    (0..grid_cols).map(move |grid_col| (grid_row, grid_col)),
                    &mut $grid,
                );
                $f(
                    (0..grid_cols)
                        .rev()
                        .map(move |grid_col| (grid_row, grid_col)),
                    &mut $grid,
                )
            });
            (0..grid_cols).for_each(|grid_col| {
                $f(
                    (0..grid_rows).map(move |grid_row| (grid_row, grid_col)),
                    &mut $grid,
                );
                $f(
                    (0..grid_rows)
                        .rev()
                        .map(move |grid_row| (grid_row, grid_col)),
                    &mut $grid,
                )
            });
        };
    }
}