80 lines
2.0 KiB
Rust
80 lines
2.0 KiB
Rust
use itertools::Itertools;
|
|
|
|
pub fn process_part_1(input: &str) -> usize {
|
|
let trees = parse_trees(input);
|
|
|
|
let rows = trees.len();
|
|
let cols = trees[0].len();
|
|
(0..rows)
|
|
.cartesian_product(0..cols)
|
|
.filter(|&(row, col)| {
|
|
let height = trees[row][col];
|
|
(0..row).all(|i| trees[i][col] < height) // up
|
|
|| (row + 1..rows).all(|i| trees[i][col] < height) // down
|
|
|| (0..col).all(|i| trees[row][i] < height) // left
|
|
|| (col + 1..cols).all(|i| trees[row][i] < height) // right
|
|
})
|
|
.count()
|
|
}
|
|
|
|
pub fn process_part_2(input: &str) -> usize {
|
|
let trees = parse_trees(input);
|
|
let rows = trees.len();
|
|
let cols = trees[0].len();
|
|
(0..rows)
|
|
.cartesian_product(0..cols)
|
|
.map(|(row, col)| {
|
|
let height = trees[row][col];
|
|
|
|
let up = match (0..row).rev().position(|i| trees[i][col] >= height) {
|
|
Some(n) => n + 1,
|
|
None => row,
|
|
};
|
|
let down = match (row + 1..rows).position(|i| trees[i][col] >= height) {
|
|
Some(n) => n + 1,
|
|
None => rows - row - 1,
|
|
};
|
|
let left = match (0..col).rev().position(|i| trees[row][i] >= height) {
|
|
Some(n) => n + 1,
|
|
None => col,
|
|
};
|
|
let right = match (col + 1..cols).position(|i| trees[row][i] >= height) {
|
|
Some(n) => n + 1,
|
|
None => cols - col - 1,
|
|
};
|
|
|
|
up * down * left * right
|
|
})
|
|
.max()
|
|
.unwrap()
|
|
}
|
|
|
|
fn parse_trees(input: &str) -> Vec<Vec<u8>> {
|
|
input
|
|
.trim()
|
|
.split('\n')
|
|
.map(|i| i.chars().map(|c| c.to_digit(10).unwrap() as u8).collect())
|
|
.collect()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
const INPUT: &str = "30373
|
|
25512
|
|
65332
|
|
33549
|
|
35390";
|
|
|
|
#[test]
|
|
fn day1() {
|
|
assert_eq!(process_part_1(INPUT), 21);
|
|
}
|
|
|
|
#[test]
|
|
fn day2() {
|
|
assert_eq!(process_part_2(INPUT), 8);
|
|
}
|
|
}
|