156 lines
3.8 KiB
Rust
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),
|
|
}
|