diff --git a/2021/src/day09.rs b/2021/src/day09.rs index fdd6e81..33fdecd 100644 --- a/2021/src/day09.rs +++ b/2021/src/day09.rs @@ -1,56 +1,6 @@ use std::cmp::Reverse; use std::io::Read; -struct LowPointsIter<'a> { - lines: &'a [&'a [u8]], - x: usize, - y: usize, -} - -impl<'a> LowPointsIter<'a> { - pub fn new(lines: &'a [&'a [u8]]) -> Self { - Self { lines, x: 0, y: 0 } - } -} - -impl Iterator for LowPointsIter<'_> { - type Item = (usize, usize); - - fn next(&mut self) -> Option { - let lines = self.lines; - - for y in self.y..self.lines.len() { - for x in self.x..self.lines[y].len() { - if x > 0 && lines[y][x - 1] <= lines[y][x] { - continue; - } - - if x + 1 < lines[y].len() && lines[y][x + 1] <= lines[y][x] { - continue; - } - - if y > 0 && lines[y - 1][x] <= lines[y][x] { - continue; - } - - if y + 1 < lines.len() && lines[y + 1][x] <= lines[y][x] { - continue; - } - - self.x = x + 1; - self.y = y; - - return Some((x, y)); - } - self.x = 0; - } - - self.y = lines.len(); - - None - } -} - pub fn part1(input: &mut dyn Read) -> String { let mut buffer = Vec::new(); input.read_to_end(&mut buffer).unwrap(); @@ -60,10 +10,31 @@ pub fn part1(input: &mut dyn Read) -> String { .filter(|s| !s.is_empty()) .collect(); - LowPointsIter::new(&lines) - .map(|(x, y)| 1 + (lines[y][x] - b'0') as i32) - .sum::() - .to_string() + let mut total_danger = 0; + + for y in 0..lines.len() { + for x in 0..lines[y].len() { + if x > 0 && lines[y][x - 1] <= lines[y][x] { + continue; + } + + if x + 1 < lines[y].len() && lines[y][x + 1] <= lines[y][x] { + continue; + } + + if y > 0 && lines[y - 1][x] <= lines[y][x] { + continue; + } + + if y + 1 < lines.len() && lines[y + 1][x] <= lines[y][x] { + continue; + } + + total_danger += 1 + (lines[y][x] - b'0') as i32; + } + } + + total_danger.to_string() } pub fn part2(input: &mut dyn Read) -> String { @@ -83,41 +54,46 @@ pub fn part2(input: &mut dyn Read) -> String { let mut sizes = Vec::with_capacity(4); - for (x, y) in LowPointsIter::new(&lines) { - todo.push((x, y)); + for y in 0..lines.len() { + for x in 0..lines[0].len() { + if visited[y][x] || lines[y][x] == b'9' { + continue; + } - let mut size = 1; - visited[y][x] = true; + todo.push((x, y)); + let mut size = 1; + visited[y][x] = true; - while let Some((x, y)) = todo.pop() { - let mut add = |x: usize, y: usize| { - if lines[y][x] != b'9' && !visited[y][x] { - size += 1; - visited[y][x] = true; - todo.push((x, y)); + while let Some((x, y)) = todo.pop() { + let mut add = |x: usize, y: usize| { + if lines[y][x] != b'9' && !visited[y][x] { + size += 1; + visited[y][x] = true; + todo.push((x, y)); + } + }; + + if x > 0 { + add(x - 1, y); } - }; - if x > 0 { - add(x - 1, y); + if x + 1 < lines[y].len() { + add(x + 1, y); + } + + if y > 0 { + add(x, y - 1) + } + + if y + 1 < lines.len() { + add(x, y + 1); + } } - if x + 1 < lines[y].len() { - add(x + 1, y); - } - - if y > 0 { - add(x, y - 1) - } - - if y + 1 < lines.len() { - add(x, y + 1); - } + sizes.push(Reverse(size)); + sizes.sort_unstable(); + sizes.truncate(3); } - - sizes.push(Reverse(size)); - sizes.sort_unstable(); - sizes.truncate(3); } sizes.into_iter().fold(1, |a, Reverse(b)| a * b).to_string()