Skip to content

Instantly share code, notes, and snippets.

@MikuroXina
Last active October 1, 2023 10:13
Show Gist options
  • Select an option

  • Save MikuroXina/d8900e937346bbadc1e78d499ad3da36 to your computer and use it in GitHub Desktop.

Select an option

Save MikuroXina/d8900e937346bbadc1e78d499ad3da36 to your computer and use it in GitHub Desktop.
Polyomino structure defintion with Rust.
#[derive(Clone, PartialEq, Eq, Hash)]
struct Poly<const W: usize, const H: usize> {
field: [[bool; W]; H],
}
impl<const W: usize, const H: usize> std::fmt::Debug for Poly<W, H> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "\"\"\"")?;
for y in 0..H {
for x in 0..W {
if self.field[y][x] {
write!(f, "#")?;
} else {
write!(f, ".")?;
}
}
writeln!(f)?;
}
writeln!(f, "\"\"\"")
}
}
impl<const W: usize, const H: usize> Poly<W, H> {
fn new(poly: Vec<Vec<char>>) -> Self {
let mut field = [[false; W]; H];
for y in 0..H {
for x in 0..W {
field[y][x] = poly[y][x] == '#';
}
}
Self { field }
}
fn turned_right(&self) -> Self {
let mut new_field = [[false; W]; H];
for y in 0..H {
for x in 0..W {
new_field[W - 1 - x][y] = self.field[y][x];
}
}
Self { field: new_field }
}
fn shifted_to(&self, dx: isize, dy: isize) -> Option<Self> {
let mut new_field = [[false; W]; H];
for y in 0..H as isize {
for x in 0..W as isize {
let to_x = x + dx;
let to_y = y + dy;
if (0..W as isize).contains(&to_x) && (0..H as isize).contains(&to_y) {
new_field[to_y as usize][to_x as usize] = self.field[y as usize][x as usize];
} else if self.field[y as usize][x as usize] {
return None;
}
}
}
Some(Self { field: new_field })
}
fn all_shifts(&self) -> impl Iterator<Item = Poly<W, H>> + Clone {
let me = self.clone();
(-(W as isize - 1)..W as isize)
.cartesian_product(-(H as isize - 1)..H as isize)
.flat_map(move |(dx, dy)| me.shifted_to(dx, dy))
}
fn is_filled(&self) -> bool {
self.field
.iter()
.all(|row| row.into_iter().all(|&cell| cell))
}
fn has_intersection(&self, other: &Self) -> bool {
for y in 0..H {
for x in 0..W {
if self.field[y][x] && other.field[y][x] {
return true;
}
}
}
false
}
fn union(&self, other: &Self) -> Self {
let mut new_field = [[false; W]; H];
for y in 0..H {
for x in 0..W {
if self.field[y][x] || other.field[y][x] {
new_field[y][x] = true;
}
}
}
Self { field: new_field }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment