92 lines
2.2 KiB
Rust
92 lines
2.2 KiB
Rust
mod canvas;
|
|
|
|
use canvas::{Canvas, Fold, Point};
|
|
|
|
use crate::prelude::*;
|
|
|
|
pub fn solution() -> Solution {
|
|
Solution::new(Day::new(13, 2021), part_1, part_2).with_expected(
|
|
"712",
|
|
" ███ █ █ █ ████ ██ ███ ██ ████
|
|
█ █ █ █ █ █ █ █ █ █ █
|
|
███ █ ████ ███ █ █ █ █ ███
|
|
█ █ █ █ █ █ █ ███ █ █
|
|
█ █ █ █ █ █ █ █ █ █ █ █
|
|
███ ████ █ █ █ ██ █ ██ █
|
|
",
|
|
)
|
|
}
|
|
|
|
fn parse(input: &str) -> Result<(Canvas, Vec<Fold>)> {
|
|
let mut canvas = Canvas {
|
|
width: 0,
|
|
height: 0,
|
|
points: HashSet::new(),
|
|
};
|
|
|
|
let mut in_folds_section = false;
|
|
let mut folds = vec![];
|
|
|
|
for line in input.lines() {
|
|
if line.is_empty() {
|
|
in_folds_section = true;
|
|
continue;
|
|
}
|
|
|
|
if in_folds_section {
|
|
let mut split = line.split('=');
|
|
let is_x_axis = split
|
|
.next()
|
|
.map(|s| s.ends_with('x'))
|
|
.ok_or_else(|| eyre!("Invalid line: {}", line))?;
|
|
|
|
let amount = split
|
|
.next()
|
|
.map(str::parse)
|
|
.ok_or_else(|| eyre!("Expected number: {}", line))??;
|
|
|
|
if is_x_axis {
|
|
folds.push(Fold::Vertical(amount));
|
|
} else {
|
|
folds.push(Fold::Horizontal(amount));
|
|
}
|
|
} else {
|
|
let (x, y) = line
|
|
.split(',')
|
|
.tuples()
|
|
.next()
|
|
.ok_or_else(|| eyre!("Invalid line: {}", line))?;
|
|
|
|
let x = x.parse()?;
|
|
let y = y.parse()?;
|
|
if canvas.width < x {
|
|
canvas.width = x;
|
|
}
|
|
|
|
if canvas.height < y {
|
|
canvas.height = y;
|
|
}
|
|
|
|
canvas.points.insert(Point(x, y));
|
|
}
|
|
}
|
|
|
|
Ok((canvas, folds))
|
|
}
|
|
|
|
fn part_1(input: &str) -> Result<String> {
|
|
let (mut canvas, folds) = parse(input)?;
|
|
canvas = canvas.fold(&folds[0]);
|
|
Ok(canvas.points.len().to_string())
|
|
}
|
|
|
|
fn part_2(input: &str) -> Result<String> {
|
|
let (mut canvas, folds) = parse(input)?;
|
|
|
|
for fold in folds {
|
|
canvas = canvas.fold(&fold);
|
|
}
|
|
|
|
Ok(format!("{}", canvas))
|
|
}
|