94 lines
2.2 KiB
Rust
94 lines
2.2 KiB
Rust
use itertools::Itertools;
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub struct Point {
|
|
pub x: usize,
|
|
pub y: usize,
|
|
}
|
|
|
|
impl Point {
|
|
fn get_bounds(points: &[Point]) -> Point {
|
|
let x = points.iter().map(|p| p.x).max().unwrap_or_default();
|
|
let y = points.iter().map(|p| p.y).max().unwrap_or_default();
|
|
Point { x, y }
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
pub enum Fold {
|
|
X(usize),
|
|
Y(usize),
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct Grid {
|
|
pub grid: Vec<Vec<bool>>,
|
|
}
|
|
|
|
impl Grid {
|
|
pub fn new(points: &[Point]) -> Self {
|
|
let bounds = Point::get_bounds(points);
|
|
let mut line = Vec::new();
|
|
for _ in 0..=bounds.x {
|
|
line.push(false)
|
|
}
|
|
let mut grid = Vec::new();
|
|
for _ in 0..=bounds.y {
|
|
grid.push(line.clone())
|
|
}
|
|
|
|
for Point { x, y } in points {
|
|
grid[*y][*x] = true;
|
|
}
|
|
Self { grid }
|
|
}
|
|
|
|
pub fn fold(&mut self, instruction: Fold) {
|
|
match instruction {
|
|
Fold::X(fold) => {
|
|
for y in 0..self.grid.len() {
|
|
for x in fold + 1..self.grid[y].len() {
|
|
self.grid[y][fold - (x - fold)] |= self.grid[y][x];
|
|
}
|
|
self.grid[y].truncate(fold)
|
|
}
|
|
}
|
|
Fold::Y(fold) => {
|
|
for y in fold + 1..self.grid.len() {
|
|
for x in 0..self.grid[0].len() {
|
|
self.grid[fold - (y - fold)][x] |= self.grid[y][x];
|
|
}
|
|
}
|
|
self.grid.truncate(fold)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn count(&self) -> usize {
|
|
self.grid
|
|
.iter()
|
|
.flat_map(|line| line.iter())
|
|
.filter(|val| **val)
|
|
.count()
|
|
}
|
|
}
|
|
|
|
impl ToString for Grid {
|
|
fn to_string(&self) -> String {
|
|
self.grid
|
|
.iter()
|
|
.map(|line| {
|
|
line.iter()
|
|
.map(|val| if *val { "#" } else { "." })
|
|
.collect::<String>()
|
|
})
|
|
.join("\n")
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct Input {
|
|
pub grid: Grid,
|
|
pub instructions: Vec<Fold>,
|
|
}
|