Simplify implementation day 8

The second part doesn't actually need to start the search at the low
points; just iterating everything and keeping track of visited spaces is
enough.

Now that the iterator is only used in part 1, we inline the iterator to
remove some overhead from the code.
This commit is contained in:
2021-12-09 12:02:07 +01:00
parent 77ce31980b
commit e0e1bc26e8

View File

@@ -1,26 +1,19 @@
use std::cmp::Reverse;
use std::io::Read;
struct LowPointsIter<'a> {
lines: &'a [&'a [u8]],
x: usize,
y: usize,
}
pub fn part1(input: &mut dyn Read) -> String {
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
impl<'a> LowPointsIter<'a> {
pub fn new(lines: &'a [&'a [u8]]) -> Self {
Self { lines, x: 0, y: 0 }
}
}
let lines: Vec<_> = buffer
.split(|&s| s == b'\n')
.filter(|s| !s.is_empty())
.collect();
impl Iterator for LowPointsIter<'_> {
type Item = (usize, usize);
let mut total_danger = 0;
fn next(&mut self) -> Option<Self::Item> {
let lines = self.lines;
for y in self.y..self.lines.len() {
for x in self.x..self.lines[y].len() {
for y in 0..lines.len() {
for x in 0..lines[y].len() {
if x > 0 && lines[y][x - 1] <= lines[y][x] {
continue;
}
@@ -37,33 +30,11 @@ impl Iterator for LowPointsIter<'_> {
continue;
}
self.x = x + 1;
self.y = y;
return Some((x, y));
}
self.x = 0;
}
self.y = lines.len();
None
total_danger += 1 + (lines[y][x] - b'0') as i32;
}
}
pub fn part1(input: &mut dyn Read) -> String {
let mut buffer = Vec::new();
input.read_to_end(&mut buffer).unwrap();
let lines: Vec<_> = buffer
.split(|&s| s == b'\n')
.filter(|s| !s.is_empty())
.collect();
LowPointsIter::new(&lines)
.map(|(x, y)| 1 + (lines[y][x] - b'0') as i32)
.sum::<i32>()
.to_string()
total_danger.to_string()
}
pub fn part2(input: &mut dyn Read) -> String {
@@ -83,9 +54,13 @@ 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;
}
todo.push((x, y));
let mut size = 1;
visited[y][x] = true;
@@ -119,6 +94,7 @@ pub fn part2(input: &mut dyn Read) -> String {
sizes.sort_unstable();
sizes.truncate(3);
}
}
sizes.into_iter().fold(1, |a, Reverse(b)| a * b).to_string()
}