AoC21/src/day13.rs

156 lines
3.8 KiB
Rust

use std::collections::HashSet;
use std::fmt::{Debug, Formatter};
pub fn day13() {
// let input = r#"
// 6,10
// 0,14
// 9,10
// 0,3
// 10,4
// 4,11
// 6,0
// 6,12
// 4,1
// 0,13
// 10,12
// 3,4
// 3,0
// 8,4
// 1,10
// 2,14
// 8,10
// 9,0
// fold along y=7
// fold along x=5
// "#;
let input = include_str!("../input/day13.txt");
let (grid, folds) = parse(input);
println!("{}x{}", grid.width, grid.height);
// dbg!(&grid);
// dbg!(&folds);
// dbg!(grid.fold(&folds[0]));
// dbg!(grid.fold(&folds[0]).fold(&folds[1]));
let grid_after_one_fold = grid.fold(&folds[0]);
// println!(
// "{}x{}",
// grid_after_one_fold.width, grid_after_one_fold.height
// );
// // dbg!(&grid_after_one_fold);
println!("dots visible: {}", grid_after_one_fold.dots_visible());
dbg!(folds.iter().fold(grid, |g, f| g.fold(f)));
}
fn parse(input: &str) -> (Grid, Vec<Fold>) {
let (grid, folds) = input.trim().split_once("\n\n").unwrap();
let folds = folds
.lines()
.map(|l| {
let (s, n) = l.trim().split_once("=").unwrap();
let coord = n.parse::<usize>().unwrap();
match s.chars().last() {
Some('x') => Fold::X(coord),
Some('y') => Fold::Y(coord),
_ => panic!(),
}
})
.collect::<Vec<_>>();
let points = grid
.lines()
.map(|l| {
let (x, y) = l.trim().split_once(",").unwrap();
let x = x.parse::<usize>().unwrap();
let y = y.parse::<usize>().unwrap();
(x, y)
})
.collect::<HashSet<_>>();
let width = points.iter().map(|(x, _)| x).max().unwrap() + 1;
let height = points.iter().map(|(_, y)| y).max().unwrap() + 1;
(
Grid {
width,
height,
points,
},
folds,
)
}
struct Grid {
width: usize,
height: usize,
points: HashSet<(usize, usize)>,
}
impl Debug for Grid {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}x{}\n", self.width, self.height).expect("write");
for y in 0..self.height {
for x in 0..self.width {
if self.points.contains(&(x, y)) {
write!(f, "#").expect("write");
} else {
write!(f, ".").expect("write");
}
}
write!(f, "\n").expect("write");
}
write!(f, "\n")
}
}
impl Grid {
fn fold(&self, fold: &Fold) -> Grid {
match fold {
Fold::X(n) => {
assert!(self.width % 2 == 1);
let new_points = self
.points
.iter()
.map(|&(x, y)| {
let new_x = if x > *n { n - (x - n) } else { x };
(new_x, y)
})
.collect::<HashSet<_>>();
Grid {
width: *n,
height: self.height,
points: new_points,
}
}
Fold::Y(n) => {
assert!(self.height % 2 == 1);
let new_points = self
.points
.iter()
.map(|&(x, y)| {
let new_y = if y > *n { n - (y - n) } else { y };
(x, new_y)
})
.collect::<HashSet<_>>();
Grid {
width: self.width,
height: *n,
points: new_points,
}
}
}
}
fn dots_visible(&self) -> usize {
self.points.len()
}
}
#[derive(Debug)]
enum Fold {
X(usize),
Y(usize),
}