Solve day 13!
This commit is contained in:
parent
32008c4408
commit
f4cb00ba69
|
@ -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(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -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))
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ mod day_07;
|
||||||
mod day_08;
|
mod day_08;
|
||||||
mod day_09;
|
mod day_09;
|
||||||
mod day_10;
|
mod day_10;
|
||||||
|
mod day_13;
|
||||||
mod day_14;
|
mod day_14;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
|
@ -30,6 +31,7 @@ fn main() -> Result<()> {
|
||||||
day_08::solve,
|
day_08::solve,
|
||||||
day_09::solve,
|
day_09::solve,
|
||||||
day_10::solve,
|
day_10::solve,
|
||||||
|
day_13::solve,
|
||||||
day_14::solve,
|
day_14::solve,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue