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) { 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::().unwrap(); match s.chars().last() { Some('x') => Fold::X(coord), Some('y') => Fold::Y(coord), _ => panic!(), } }) .collect::>(); let points = grid .lines() .map(|l| { let (x, y) = l.trim().split_once(",").unwrap(); let x = x.parse::().unwrap(); let y = y.parse::().unwrap(); (x, y) }) .collect::>(); 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::>(); 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::>(); 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), }