1
Fork 0
advent-of-code/source/year_2021/day_13/canvas.rs

81 lines
1.7 KiB
Rust

//! [`Point`], [`Fold`] and [`Canvas`] implementation.
use std::{collections::HashSet, fmt::Display};
/// A point coordinate.
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct Point(pub isize, pub isize);
/// The types of fold that can be made.
#[derive(Debug)]
pub enum Fold {
/// A horizontal fold going left.
Horizontal(isize),
/// A vertical fold going up.
Vertical(isize),
}
/// The canvas of the paper.
#[derive(Debug)]
pub struct Canvas {
/// The width of the canvas.
pub width: isize,
/// The height of the canvas.
pub height: isize,
/// The points on the canvas.
pub points: HashSet<Point>,
}
impl Canvas {
/// Perform a fold on the canvas and return the resulting version of it.
pub fn fold(self, fold: &Fold) -> Self {
let (width, height) = match fold {
Fold::Horizontal(amount) => (self.width, *amount),
Fold::Vertical(amount) => (*amount, self.height),
};
let mut points = HashSet::new();
for Point(x, y) in self.points {
if y > height {
points.insert(Point(x, height - (y - height)));
continue;
}
if x > width {
points.insert(Point(width - (x - width), y));
continue;
}
points.insert(Point(x, y));
}
Self {
width,
height,
points,
}
}
}
impl Display for Canvas {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for y in 0..self.height {
for x in 0..self.width {
if x % (self.width / 8) == 0 {
write!(f, " ")?;
}
if self.points.contains(&Point(x, y)) {
write!(f, "")?;
} else {
write!(f, " ")?;
}
}
writeln!(f)?;
}
Ok(())
}
}