Last active
December 14, 2021 12:29
-
-
Save neofight78/a7f9cba8ac74dcc68d50719d618c38af to your computer and use it in GitHub Desktop.
Advent of Code 2021 - Day 13: Transparent Origami
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Clone, Copy)] | |
enum Fold { | |
Horizontal(usize), | |
Vertical(usize), | |
} | |
impl From<&str> for Fold { | |
fn from(fold: &str) -> Self { | |
let (instruction, position) = fold.split_once('=').unwrap(); | |
let position = position.parse::<usize>().unwrap(); | |
match instruction { | |
"fold along y" => Horizontal(position), | |
"fold along x" => Vertical(position), | |
_ => panic!("Invalid fold!"), | |
} | |
} | |
} | |
struct Paper { | |
paper: Vec<Vec<bool>>, | |
width: usize, | |
height: usize, | |
} | |
impl Display for Paper { | |
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | |
for row in 0..self.height { | |
for col in 0..self.width { | |
write!(f, "{} ", if self.paper[row][col] { '#' } else { '.' })?; | |
} | |
writeln!(f)?; | |
} | |
Ok(()) | |
} | |
} | |
impl From<&str> for Paper { | |
fn from(dots: &str) -> Self { | |
let dots = dots | |
.lines() | |
.map(|d| { | |
let parts = d.split_once(',').unwrap(); | |
( | |
parts.0.parse::<usize>().unwrap(), | |
parts.1.parse::<usize>().unwrap(), | |
) | |
}) | |
.collect::<Vec<_>>(); | |
let width = dots.iter().map(|d| d.0).max().unwrap() + 1; | |
let height = dots.iter().map(|d| d.1).max().unwrap() + 1; | |
let mut paper = vec![vec![false; width]; height]; | |
dots.iter().for_each(|(col, row)| paper[*row][*col] = true); | |
Self { | |
paper, | |
width, | |
height, | |
} | |
} | |
} | |
impl Paper { | |
fn count_dots(&self) -> usize { | |
self.paper | |
.iter() | |
.map(|r| r.iter().filter(|&&d| d).count()) | |
.sum() | |
} | |
fn fold(&mut self, fold: Fold) { | |
match fold { | |
Horizontal(position) => { | |
let (a, b) = self.paper.split_at_mut(position); | |
for row in 0..a.len() { | |
for col in 0..self.width { | |
a[row][col] |= b.get(a.len() - row).map_or(false, |r| r[col]); | |
} | |
} | |
self.paper.truncate(position); | |
self.height = position; | |
} | |
Vertical(position) => { | |
for row in 0..self.height { | |
let (a, b) = self.paper[row].split_at_mut(position); | |
for col in 0..a.len() { | |
a[col] |= b.get(a.len() - col).unwrap_or(&false); | |
} | |
self.paper[row].truncate(position); | |
} | |
self.width = position; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment