2021: day05: use custom iterator
This commit is contained in:
parent
48f1a4ffeb
commit
56a5379a1b
|
@ -1,6 +1,6 @@
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::iter;
|
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
|
||||||
|
@ -52,6 +52,57 @@ fn part2(input: &str) -> Result<usize> {
|
||||||
Ok(grid.into_values().filter(|c| *c > 1).count())
|
Ok(grid.into_values().filter(|c| *c > 1).count())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PointIterator {
|
||||||
|
current: (usize, usize),
|
||||||
|
to: (usize, usize),
|
||||||
|
dx: Ordering,
|
||||||
|
dy: Ordering,
|
||||||
|
done: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PointIterator {
|
||||||
|
fn new(from: (usize, usize), to: (usize, usize)) -> Self {
|
||||||
|
Self {
|
||||||
|
current: from,
|
||||||
|
to,
|
||||||
|
dx: from.0.cmp(&to.0),
|
||||||
|
dy: from.1.cmp(&to.1),
|
||||||
|
done: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for PointIterator {
|
||||||
|
type Item = (usize, usize);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.done {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (x, y) = self.current;
|
||||||
|
|
||||||
|
if x == self.to.0 && y == self.to.1 {
|
||||||
|
self.done = true;
|
||||||
|
return Some((x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.dx {
|
||||||
|
Ordering::Less => self.current.0 += 1,
|
||||||
|
Ordering::Greater => self.current.0 -= 1,
|
||||||
|
Ordering::Equal => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.dy {
|
||||||
|
Ordering::Less => self.current.1 += 1,
|
||||||
|
Ordering::Greater => self.current.1 -= 1,
|
||||||
|
Ordering::Equal => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some((x, y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Line {
|
struct Line {
|
||||||
from: (usize, usize),
|
from: (usize, usize),
|
||||||
|
@ -67,28 +118,8 @@ impl Line {
|
||||||
self.to.0 == self.from.0
|
self.to.0 == self.from.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cells(&self) -> Box<dyn Iterator<Item = (usize, usize)>> {
|
fn cells(&self) -> impl Iterator<Item = (usize, usize)> {
|
||||||
fn inclusive_range_any_order(a: usize, b: usize) -> Box<dyn Iterator<Item = usize>> {
|
PointIterator::new(self.from, self.to)
|
||||||
if a < b {
|
|
||||||
Box::new(a..=b) as Box<dyn Iterator<Item = _>>
|
|
||||||
} else {
|
|
||||||
Box::new((b..=a).rev())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.is_horizontal() {
|
|
||||||
Box::new(
|
|
||||||
inclusive_range_any_order(self.from.0, self.to.0).zip(iter::repeat(self.from.1)),
|
|
||||||
) as Box<dyn Iterator<Item = _>>
|
|
||||||
} else if self.is_vertical() {
|
|
||||||
Box::new(
|
|
||||||
iter::repeat(self.from.0).zip(inclusive_range_any_order(self.from.1, self.to.1)),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
let x_range = inclusive_range_any_order(self.from.0, self.to.0);
|
|
||||||
let y_range = inclusive_range_any_order(self.from.1, self.to.1);
|
|
||||||
Box::new(x_range.zip(y_range))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue