#![feature(test)] extern crate test; use itertools::Itertools; use std::iter::repeat; use aoc2022::{boilerplate, common::*}; const DAY: usize = 08; type Parsed = Vec>; fn parse_input(raw: &str) -> Parsed { raw.lines().map(|l| l.as_bytes().to_vec()).collect() } fn is_visible_1d<'a>(iter: impl IntoIterator) -> Vec { iter.into_iter() .scan(0, |max, tree| { let visible = tree > max; *max = *tree.max(max); Some(visible) }) .collect() } fn part1(parsed: &Parsed) -> usize { let size = parsed.len(); // input is always square let a: Vec<_> = parsed.iter().map(is_visible_1d).collect(); let b: Vec<_> = parsed .iter() .map(|l| { let mut v = is_visible_1d(l.iter().rev()); v.reverse(); v }) .collect(); let c: Vec<_> = (0..size).map(|i| is_visible_1d(parsed.iter().map(|row| &row[i]))).collect(); let d: Vec<_> = (0..size) .map(|i| { let mut v = is_visible_1d(parsed.iter().rev().map(|row| &row[i])); v.reverse(); v }) .collect(); (0..size).flat_map(|i| repeat(i).zip(0..size)).filter(|&(i, j)| a[i][j] || b[i][j] || c[j][i] || d[j][i]).count() } fn part2(parsed: &Parsed) -> usize { let size = parsed.len(); // input is always square (1..size - 1) .flat_map(|i| repeat(i).zip(1..size - 1)) .map(|(i, j)| { let tree = parsed[i][j]; let mut heights = ((i + 1)..size).map(|i| parsed[i][j]).peekable(); let a = heights.peeking_take_while(|&t| t < tree).count() + heights.peek().map(|_| 1).unwrap_or(0); let mut heights = (0..i).rev().map(|i| parsed[i][j]).peekable(); let b = heights.peeking_take_while(|&t| t < tree).count() + heights.peek().map(|_| 1).unwrap_or(0); let mut heights = ((j + 1)..size).map(|j| parsed[i][j]).peekable(); let c = heights.peeking_take_while(|&t| t < tree).count() + heights.peek().map(|_| 1).unwrap_or(0); let mut heights = (0..j).rev().map(|j| parsed[i][j]).peekable(); let d = heights.peeking_take_while(|&t| t < tree).count() + heights.peek().map(|_| 1).unwrap_or(0); a * b * c * d }) .max() .unwrap() } #[cfg(test)] const TEST_OUTPUT: &[bool] = &[true, true, false, true, false]; boilerplate! { TEST_INPUT == "30373 25512 65332 33549 35390", tests: { part1: { TEST_INPUT => 21 }, part2: { TEST_INPUT => 8 }, }, unittests: { is_visible_1d: { [1, 3, 2, 4, 2] => TEST_OUTPUT, }, }, bench1 == 1543, bench2 == 595080, bench_parse: Vec::len => 99, }