-
Notifications
You must be signed in to change notification settings - Fork 0
/
lib.rs
85 lines (76 loc) · 2.17 KB
/
lib.rs
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
use itertools::Itertools;
fn parse_grid(input: &str) -> Vec<Vec<u32>> {
input
.lines()
.map(|line| {
line.chars()
.map(|char| char.to_digit(10).unwrap())
.collect()
})
.collect()
}
fn get_up_down_left_right(grid: &[Vec<u32>], x: usize, y: usize) -> Vec<Vec<u32>> {
let column = grid.iter().map(|row| row[x]).collect::<Vec<u32>>();
let (up, down) = column.split_at(y);
let (left, right) = grid[y].split_at(x);
vec![
up.iter().rev().cloned().collect(),
down[1..].to_vec(),
left.iter().rev().cloned().collect(),
right[1..].to_vec(),
]
}
pub fn solution_a(input: &str) -> usize {
let grid = parse_grid(input);
let len = grid.len();
(1..len - 1)
.cartesian_product(1..len - 1)
.map(|(y, x)| {
let height = grid[y][x];
get_up_down_left_right(&grid, x, y)
.iter()
.map(|direction| direction.iter().all(|h| *h < height))
.any(|direction_visible| direction_visible)
})
.filter(|direction_visible| *direction_visible)
.count()
+ (len - 1) * 4
}
pub fn solution_b(input: &str) -> usize {
let grid = parse_grid(input);
let len = grid.len();
(1..len - 1)
.cartesian_product(1..len - 1)
.map(|(y, x)| {
let height = grid[y][x];
get_up_down_left_right(&grid, x, y)
.iter()
.map(|direction| {
direction
.iter()
.position(|h| *h >= height)
.map(|p| p + 1)
.unwrap_or_else(|| direction.len())
})
.product()
})
.max()
.unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "30373
25512
65332
33549
35390";
const INPUT: &str = include_str!("input.txt");
#[test]
fn it_works() {
assert_eq!(solution_a(TEST_INPUT), 21);
println!("{}", solution_a(INPUT));
assert_eq!(solution_b(TEST_INPUT), 8);
println!("{}", solution_b(INPUT));
}
}