75 lines
1.7 KiB
Rust
75 lines
1.7 KiB
Rust
#![warn(clippy::pedantic)]
|
|
|
|
use std::io::{stdin, Read};
|
|
|
|
use aoc::*;
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
struct Tree {
|
|
height: u32,
|
|
visible: bool,
|
|
score: usize,
|
|
}
|
|
|
|
fn make_visible<'a>(trees: impl IntoIterator<Item = &'a mut Tree>) {
|
|
let mut seen: Vec<Tree> = Vec::new();
|
|
let mut highest: Option<Tree> = None;
|
|
|
|
for tree in trees {
|
|
let update = match highest {
|
|
None => true,
|
|
Some(highest) => tree.height > highest.height,
|
|
};
|
|
|
|
if update {
|
|
tree.visible = true;
|
|
highest = Some(*tree);
|
|
}
|
|
|
|
let mut score = 0;
|
|
for t in seen.iter().rev() {
|
|
score += 1;
|
|
if t.height >= tree.height {
|
|
break;
|
|
}
|
|
}
|
|
tree.score *= score;
|
|
seen.push(*tree);
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let mut data = String::new();
|
|
stdin().read_to_string(&mut data).unwrap();
|
|
|
|
let mut grid: Vec<Vec<Tree>> = data
|
|
.lines()
|
|
.map(|line| {
|
|
line.chars()
|
|
.map(|c| Tree {
|
|
height: c.to_digit(10).unwrap(),
|
|
visible: false,
|
|
score: 1,
|
|
})
|
|
.collect()
|
|
})
|
|
.collect();
|
|
|
|
for line in &mut grid {
|
|
make_visible(line.iter_mut());
|
|
make_visible(line.iter_mut().rev());
|
|
}
|
|
|
|
let width = grid[0].len();
|
|
for i in 0..width {
|
|
make_visible(grid.iter_mut().map(|l| &mut l[i]));
|
|
make_visible(grid.iter_mut().map(|l| &mut l[i]).rev());
|
|
}
|
|
|
|
println!("{:?}", grid.iter().flatten().filter(|&t| t.visible).count());
|
|
println!(
|
|
"{:?}",
|
|
grid.iter().flatten().map(|t| t.score).max().unwrap()
|
|
);
|
|
}
|