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

98 lines
2.3 KiB
Rust

//! Day 13 of 2021.
mod canvas;
use canvas::{Canvas, Fold, Point};
use crate::prelude::*;
/// Get the solution for day 13 of 2021.
pub fn solution() -> Solution {
Solution::new(Day::new(13, 2021), part_1, part_2).with_expected(
"712",
" ███ █ █ █ ████ ██ ███ ██ ████
█ █ █ █ █ █ █ █ █ █ █
███ █ ████ ███ █ █ █ █ ███
█ █ █ █ █ █ █ ███ █ █
█ █ █ █ █ █ █ █ █ █ █ █
███ ████ █ █ █ ██ █ ██ █
",
)
}
/// Parse the canvas and list of folds to perform from the puzzle input.
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))
}
/// The logic to solve part one.
fn part_1(input: &str) -> Result<String> {
let (mut canvas, folds) = parse(input)?;
canvas = canvas.fold(&folds[0]);
Ok(canvas.points.len().to_string())
}
/// The logic to solve part two.
fn part_2(input: &str) -> Result<String> {
let (mut canvas, folds) = parse(input)?;
for fold in folds {
canvas = canvas.fold(&fold);
}
Ok(format!("{}", canvas))
}