Detect unique chains

This commit is contained in:
2023-03-23 17:18:59 +01:00
parent 915949fb98
commit ac7c9b30de
5 changed files with 177 additions and 15 deletions

View File

@@ -41,8 +41,8 @@ impl Alignment {
/// Test if two positions are aligned in this direction.
pub fn is_aligned(self, a: Position2d, b: Position2d) -> bool {
match self {
Alignment::Horizontal => a.x == b.x,
Alignment::Vertical => a.y == b.y,
Alignment::Horizontal => a.y == b.y,
Alignment::Vertical => a.x == b.x,
}
}
}
@@ -67,6 +67,53 @@ impl Position2d {
None
}
}
/// Returns an iterator over all positions relative to this position in the given direction.
///
/// If the positions are not aligned in any direction, the iterator will be empty.
/// If the end position is before the start position, the iterator will be empty.
pub fn iterate_to(self, end: Position2d, offset: (usize, usize)) -> RelativeIterator {
if (self.x != end.x && self.y != end.y) || self.x > end.x || self.y > end.y {
return RelativeIterator {
pos: self,
end: self,
offset: (0, 0),
};
}
RelativeIterator {
pos: self,
end,
offset,
}
}
pub fn manhattan_distance(self, other: Position2d) -> usize {
self.x.abs_diff(other.x) + self.y.abs_diff(other.y)
}
pub fn is_contiguous(self, other: Position2d) -> bool {
self.manhattan_distance(other) == 1
}
}
pub struct RelativeIterator {
pos: Position2d,
end: Position2d,
offset: (usize, usize),
}
impl Iterator for RelativeIterator {
type Item = Position2d;
fn next(&mut self) -> Option<Self::Item> {
if self.pos == self.end {
None
} else {
let pos = self.pos;
self.pos = Position2d::new(self.pos.x + self.offset.0, self.pos.y + self.offset.1);
Some(pos)
}
}
}
impl From<(usize, usize)> for Position2d {