#[path = "../lib.rs"] mod lib; fn get_map() -> Vec> { let mut map = vec![]; for line in lib::iter_input() { map.push(line.bytes().collect()); } return map; } fn mark_visible( heights: &Vec>, visible: &mut Vec>, vertical: bool, reverse: bool, ) { let mut max; for a in 0..heights.len() { max = 0; for b in 0..heights.len() { let c = if reverse { heights.len() - (b + 1) } else { b }; let (y, x) = if vertical { (c, a) } else { (a, c) }; if heights[y][x] > max { max = heights[y][x]; visible[y][x] = true; } } } } fn part1(heights: &Vec>) -> usize { let mut visible: Vec> = heights.iter().map(|row| row.iter().map(|_| false).collect() ).collect(); mark_visible(heights, &mut visible, false, false); mark_visible(heights, &mut visible, false, true); mark_visible(heights, &mut visible, true, false); mark_visible(heights, &mut visible, true, true); return visible.concat().iter().filter(|v| **v).count(); } fn count_visible(value: u8, others: impl Iterator) -> u64 { let mut count = 0; for other in others { count += 1; if other >= value { return count; } } return count; } fn part2(heights: &Vec>) -> u64 { let rows = heights.len(); let cols = heights[0].len(); let mut max = 0; for x in 0..cols { for y in 0..rows { let value = heights[y][x]; let score = count_visible(value, (0..x).rev().map(|x1| heights[y][x1])) * count_visible(value, (x + 1..cols).map(|x1| heights[y][x1])) * count_visible(value, (0..y).rev().map(|y1| heights[y1][x])) * count_visible(value, (y + 1..rows).map(|y1| heights[y1][x])); if score > max { max = score; } } } return max; } fn main() { let heights = get_map(); assert_eq!(heights.len(), heights[0].len()); println!("part1: {}", part1(&heights)); println!("part2: {}", part2(&heights)); }