1
Fork 0

Solve day 13!

This commit is contained in:
Bauke 2021-12-14 20:23:48 +01:00
parent 32008c4408
commit f4cb00ba69
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
3 changed files with 159 additions and 0 deletions

69
source/day_13/canvas.rs Normal file
View File

@ -0,0 +1,69 @@
use std::{collections::HashSet, fmt::Display};
#[derive(Debug, Hash, PartialEq, Eq)]
pub struct Point(pub isize, pub isize);
#[derive(Debug)]
pub enum Fold {
Horizontal(isize),
Vertical(isize),
}
#[derive(Debug)]
pub struct Canvas {
pub width: isize,
pub height: isize,
pub points: HashSet<Point>,
}
impl Canvas {
pub fn fold(self, fold: &Fold) -> Self {
let (width, height) = match fold {
Fold::Horizontal(amount) => (self.width, *amount),
Fold::Vertical(amount) => (*amount, self.height),
};
let mut points = HashSet::new();
for Point(x, y) in self.points {
if y > height {
points.insert(Point(x, height - (y - height)));
continue;
}
if x > width {
points.insert(Point(width - (x - width), y));
continue;
}
points.insert(Point(x, y));
}
Self {
width,
height,
points,
}
}
}
impl Display for Canvas {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for y in 0..self.height {
for x in 0..self.width {
if x % (self.width / 8) == 0 {
write!(f, " ")?;
}
if self.points.contains(&Point(x, y)) {
write!(f, "")?;
} else {
write!(f, " ")?;
}
}
writeln!(f)?;
}
Ok(())
}
}

88
source/day_13/mod.rs Normal file
View File

@ -0,0 +1,88 @@
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))
}

View File

@ -12,6 +12,7 @@ mod day_07;
mod day_08;
mod day_09;
mod day_10;
mod day_13;
mod day_14;
fn main() -> Result<()> {
@ -30,6 +31,7 @@ fn main() -> Result<()> {
day_08::solve,
day_09::solve,
day_10::solve,
day_13::solve,
day_14::solve,
];