From 951ed73024eb1654e011c6756bcce1ce352af96b Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Thu, 8 Dec 2022 22:57:36 +0100 Subject: [PATCH] Slow O(n) algorithm for part 2 --- 2022/src/day08.rs | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/2022/src/day08.rs b/2022/src/day08.rs index 483f053..b0784a1 100644 --- a/2022/src/day08.rs +++ b/2022/src/day08.rs @@ -1,3 +1,5 @@ +use std::cmp::Ordering; + use anyhow::Context; use anyhow::Result; @@ -63,16 +65,32 @@ pub fn part1(input: &[u8]) -> Result { fn scenery<'a>( values: impl IntoIterator, visible: impl IntoIterator, + tree_stack: &mut Vec<(usize, u8)>, ) { - let mut last_seen = [0; 10]; + tree_stack.clear(); for (i, (&val, score)) in values.into_iter().zip(visible).enumerate() { - let val = val - b'0'; - let visible = i - last_seen[val as usize]; - if i > 0 { - *score *= visible; - last_seen[..=(val as usize)].fill(i); + let mut first = 0; + + while let Some((pos, other)) = tree_stack.pop() { + match other.cmp(&val) { + Ordering::Less => (), + Ordering::Equal => { + first = pos; + break; + } + Ordering::Greater => { + tree_stack.push((pos, other)); + first = pos; + break; + } + } + } + + tree_stack.push((i, val)); + + *score *= i - first; } else { *score = 0; } @@ -88,15 +106,18 @@ pub fn part2(input: &[u8]) -> Result { let mut score = vec![1; width * height]; + let mut tree_stack = Vec::new(); + // Horizontal striping for (y, row) in input.chunks_exact(width + 1).enumerate() { // First, left to right - scenery(&row[..width], &mut score[(y * width)..]); + scenery(&row[..width], &mut score[(y * width)..], &mut tree_stack); // Then right to left scenery( row[..width].iter().rev(), score[(y * width)..(y * width + width)].iter_mut().rev(), + &mut tree_stack, ); } @@ -106,12 +127,14 @@ pub fn part2(input: &[u8]) -> Result { scenery( input[x..].iter().step_by(width + 1), score[x..].iter_mut().step_by(width), + &mut tree_stack, ); // Bottom to top scenery( input[x..].iter().step_by(width + 1).rev(), score[x..].iter_mut().step_by(width).rev(), + &mut tree_stack, ) }