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

89 lines
1.8 KiB
Rust

use std::collections::HashSet;
use color_eyre::{eyre::eyre, Result};
mod canvas;
use canvas::{Canvas, Fold, Point};
use itertools::Itertools;
pub fn solve() -> Result<()> {
let input_data = include_str!("../../data/day_13.txt").trim();
println!("Day 13 Part 1: {}", part_1(input_data)?);
println!("Day 13 Part 2:\n{}", part_2(input_data)?);
Ok(())
}
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 == "" {
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<usize> {
let (mut canvas, folds) = parse(input)?;
canvas = canvas.fold(&folds[0]);
Ok(canvas.points.into_iter().count())
}
fn part_2(input: &str) -> Result<String> {
let (mut canvas, folds) = parse(input)?;
for fold in folds {
canvas = canvas.fold(&fold);
}
Ok(format!("{}", canvas))
}