diff --git a/inputs/day17.txt b/inputs/day17.txt new file mode 100644 index 0000000..bc6acad --- /dev/null +++ b/inputs/day17.txt @@ -0,0 +1 @@ +><><<<><<<<>>>><<<><>>><><<<<><<<>><<>>>><<<>>>><<<>><>>>><<<>>><<<>><<>><<<<>><<>>>><<<<><<><<<<>>><<<<>><<>>>><<<<>>><>><<<<>>><>>><<<<>>>><<<<>>><<<<>>>><<<<>><<>>>><<><<<>><>>><<>>>><<<<>>>><<<<>><>>><<<>>><<<>><>>>><<<<>><<<>>><<<<>>><<>>>><>>><<<>>>><<<<><<>>>><<>>><<<>>>><<><<<><<<>>><>>>><<<><<<<><<>><>>>><<<>>>><<<<>><<>>><<><>>>><<>><<<<>><<<><<>>>><<><<<>>><<><<<>>><<<>><<><<<>>>><<<<>>><<<<>>><<>><>>><<><<<><<>><>>><>>>><<<<>><<>>><<<>>><><<>>>><<>>><<>><<>><><><>><<<>>>><>><<<>>>><>>><>><<<<>>>><<<<>>><<<<><<<>>>><<<>><<<><<>><<>>><<<>>><<<>>>><<<>><<<<><<><<<<>>>><<>>><<<>>>><<<<>>>><<<>>>><<>><><<<<>>><<><<>>><<><<<<>>><<<>><<<<><<>>>><<<<>>><>><<<>><<>>>><<<>>><<>>>><>>><<<>><<>><<><<><<<><<<>>>><<<<>>><<<>><><>><<<<>><<<<>>><<<>>><>>><<><<<><<<><>><<<>>><<><><<>>><>><<<<>>>><>>><<>>><><<>><<<<>><>>><>>>><><<>>>><<><><<<>>>><>>>><>>><>>><<<>>>><>>>><>>><<<<>>><<>>>><<><<<<>>><<<><<<<>><<><<<>><<><<><<<>><<<<>>>><>><<<<>>><><<>>><<<>><<>>>><<>><<><<<>>><>><<<>><<<>><>><>>>><<<<>><<<>>><<>><<>>>><>>><<<<>><<<<>><<>><<<<>>><<<<>>><>>><<<<>>>><<>><<<>><>>><<<>>>><<<>>><><<<<>>><<<>>><><<<<>>>><>><<>><<<><<>>>><<<>><<<<>><<<<>>>><<<<>>>><>>><<<>>>><><<<>>>><>>><<<>>>><>>>><<<<><<<>>>><<<>>><>>>><>>>><<<<>>><>>><>>><<><<<<><<<<><<<><<<>>>><<<<>>>><<>>>><<<><<<>><>>>><<>>><<<<><<>>>><>>><><<<<>><<<<>>>><<<<>>>><<<<>><<>><<<<>><<<><>>>><<<>>>><><<><>>>><<<<>><>>><<>>>><<<>>>><<>>><<<<>>>><<<>>>><<>>><<>>><<<<><<>><<<<><<<>>><<<><<<>>>><<><<<<>>>><<<<>>>><<>><>><<>><<>><<<<><<>>>><>><>><<<><>><<<<>><<<<><<<<>>>><<>><<><>>>><<<<><<<>><<<>>>><<<<>>>><>><>>>><<<<>>>><<<>>>><<<><<<<>>>><<>><<<<>>><<<>>><>><<<<>><<>>>><<<<>>>><<>><<>><<<>>><<<<>><<<<><<>><<><<><<<>>>><<>>>><<<<>>>><>>><>>><<<>><><<>>><<>><<<<>>>><<<<>>>><<<<><<><<<>><<<<>><<>>><<<<>>>><<<><<<<>><<<<>>>><<<<>>><<<>>><<<>>>><<<<>>>><<<>>><<><<>>>><<>><<<>>><<<<>><><>>>><<<<><<<>><<><><<>>>><>><<<>>>><<<>>>><<>>>><<<>>><<<<>>>><<<<>>>><<>>>><<>><>>>><>><<<<>><<<<><>><>>><<<<>><<>><><>>>><<<>>>><><>>><>>><><<<<><><>>>><>><<<<><<>><<>><<><<>><<<>>><<>><<<<>>>><><<<>>><><<>><><<<>><<><<<>>>><<>>><<>><<<>><<<>>>><>>>><<>>>><<<><><>>>><<>><>>>><<<>><<<>>>><<<><>>>><<>>>><<<<>><<<<>>><<<>><<<>>>><<<<>>>><<<>>><<<>>>><<>>><<<><<<>>>><<<<>>><<<>>><<<>><><<<>>>><<>>><>>>><><<><<<>>><<<<><>>>><<<<>>>><>>><<>>><<<><<>><><<<<>><>>>><<<<>>>><<<><<>>><<><>><<<<><<<>>>><<<<><<<<>>>><<<<><<<<>>>><<<>><<<>>><<>><<<>>><>>>><<>>>><<<<><<<>>><<<<>>>><<>><<<<><>><>>>><>>><<<><<<><>><<><<<>>><><>>><<<>>>><<<><>><<<>>><>>><>><>><>>>><<<<>>><<<><<<<>>>><<<<>><<>>>><<><<>>>><<>><<>><>>>><>>><<<<><<>><>>>><>><<><<<<>>><<>>>><<<<><><>>><<>><<<>><<>>><>><<<>>><<<<>><>>><<<>>>><<<<>>><<<><<<><<>>>><>>>><<>>><<<<>><><<<>><<<>><>><><<><<<<>><<<>><<<>>>><<>><<<>>>><>>>><<<<>>><<>><<>>><>>><>>><<<<>><<<<><>>>><><<>>><<<<>>>><>>><>><<<<>>>><>>><<<<>>><>>>><<><<<>><<<>>>><<<>>>><>>><<><<<>><<<<>>><<>>>><<>><>>><<><<<>>><>>>><>>><<<<>>>><>>>><>>><><<><<<>><<<<>>><<<<>><<<<><<<>>>><<>>>><>><<><<<<>>>><<>><>>><>>><<<>><<<<>>><><<<>><<<<><<<<>>>><<<><<>><<>><<<<>><<><>>>><>>>><<<>>><<<<>>>><<<<>>>><<<<>><<<>>><<<<>>><>>><<><<<<><<<<>>>><<>>><<<<><>><<>>><<<>>>><><<<<>>><<><>>>><>>><<<><<><<<>>>><<<>><<>>><><<<<><<<><<>><<<<><>>>><>>>><<<>><<<<>>><<>>>><><<><<<<><>>>><<<<>>><>>>><<>><<<>>>><<<<>>><>>><<<><<<>><>>><><<<<>>><<<>>>><<<<>>><>><<>>><<<>><<<<>>><<<><<<<>>><<<>>>><<<<>>><><<>>><<<>>><<><<<<>>><<><<<<>><<>><><<<<>>>><>>><>><<<>>><>>><<<<>>><<<<><<<<><<<<>>>><<<>>><><<<<>>><<<>><<<>>><<><<<>>>><<<<><<>>><<<<>>><<<>>><<<<>>>><<<>>><>>>><<<><>>><><<><>>>><>>>><>><>>>><<>><<>><>>><<>>>><<>>><>><<<>>><<<><<>>><>><<>>>><><<<>>>><<>>>><<>>><<>>><<<>>><<>>>><<<><<<>>>><<>>><<<<><<>>>><<>><<<>><<<<><>>>><<<><<<><><<<<><<<<>>>><<>><><>>><<>><>>>><<<<>>>><>><<>><<<><<<<>><<>>><<<<>>><><<<><<<<>><<<<>><>>>><<<>>>><<<<><<>><<>><<<>>><<><<<>>>><><><<<<>><<>>>><<><<<><><>><<>>><<<<>>><<<<>>>><<<<>><>>>><>>>><<<>>>><>><<>>>><><<<<>>>><><<<<>>><<<<>>><<<<>><>><>><<<><<<<>>><<<><<<>><>>>><<<>>><<<<>>><<><<<<>>><<<>>><<><<>>><<>><<<>><<><<<<><<<<>>><>>>><<<<>><><<<<><<<>>><<<<>>><<<>><<<>>><<<>>><<<>>>><<<<>>>><<<>>><<>>><<<<><<<>><><<><<>>><<<>><<><<>>><<<>>><<>>>><<<<>>>><<<>>><<><<<>>><>><<<><<<<>><<<<>>><<<>>>><<<><<<><<<<>>>><<<<>>>><<>>><<>>>><<>>><<<<>>>><<<<>><<><<>><<<<><>>>><><<<>>><<<>>>><<<<>>><<><>><>>>><<<<>><<<<>><<>>>><<<><<<>>><<>>><<<>>>><<>>><<<>>>><<<<>><<<<>>>><<<<><<<<>>><<<>><<<>>><<>><<>><>>><>>>><<<<><>><<<>><>>>><<<>>>><<><<>><>>>><<<><><>>>><<><<>>>><<>>><>><<<<><<<>>><<>><<<>><<>><<><>>><>><<<<>><<<>><>>><>><<>><<<><<><<>>><<>>><<><<>>><<>>>><>>><<><<<><<>>><<<<>>><<><>>><<<<><><><<<<>>><><>>><>>>><<<><<<>>><<<<>>>><>>>><<>>><>><>><>><<<<>>><<><<><<<><<<>><>><>>><<>>>><<<>><>>>><<<><<<<>><<<<>><<<<>><<>><<<<>>><<<>><<>>><<<<><<>>><><<<><<>>>><<<<>>><<>><<<>>><><<<<>>><<><<<<>>>><>><<<<><>>><<<>>>><><>>><<<><<<><<<<>>>><>>><<<>>>><<>>><>>>><><<<>><<>>>><><<>>>><<<>>>><<<<><<<<><<<>>><<>>><<<<>>><<>>><<>>>><<<>>>><><<<<>>><><<<>>>><>><<><<<<>>>><<<<>>>><><><>><<<>>><<><<<>>>><<>><>>><>>><<<<>>><>><<>>>><<>><<<<><<<>>><<<<><<<>>><<<<><<<>>>><<<<><<>>>><<>><<<<>>><<>><<>><<>>><>>><<<>>><>>>><<<<>>>><<<<><>><<>>>><<<<><<>>>><<<>>>><>>><<>><<<<>><<<><<>>>><<<><<<<><<<<>>>><<<<>><<<><<>>>><>>><<<>>><<<<>><<<<>>><<<><<<>>>><<<>>>><<>><<>>>><<>>>><<<<>>><<>><<<>><<<<><<<><<<>>>><<><><>>>><<>>>><>>><<<<>>><<>><<<>>>><<<>><<<>><<<>><<>><>>><<<>>><<>>>><>><>>><<<>><<<>>>><<<>><<>>>><><><<>>>><<<<><<>><<><<<>><<><>>>><>><<<<>><><<<>><<>><<><<<>><<<>>><<>>>><<><>>>><<<><<>>>><>><<<>>>><<><<>>><>>>><>>>><<>><<>>><<><<<><<<<>><<<><<<<><<<>><<<<>>><<<>><<><<>><<<<><<>>><>>><<<><>><<<>>>><<<<>><<>>>><>>>><<<<>><<<>>>><>>><<>><>>><<<>>>><>>><<<<>>>><>><><<<<>>><<<>><<<>><<<><>>><<<>><<<<>><<><<>><<<<>>><>>>><<<>>>><<>><<<<>><<<<>>><<<<>>>><<><><<<>>>><<><>>><<>><<<<>>>><><<>>><<<<>><<<<><<<>>>><>>>><<>>><<<<>><>><<<<>>><<>>><<<>>>><<<>>><<<<><<<>>><<>><>>><<<<><<><<<>>>><<<>>>><<<><<>><<<<><<>><<<<>>>><>><<<><><<<>>>><<<<>><>><<<<>>><<<<><>>>><<<<>><<>>>><>>>><<<>><<<>>>><>>><<<<>>>><<<>>>><><>>>><<>>><<>>><>>><<>>>><<>>>><<<<>>>><><<<>><<><>>>><<<<>>>><<<<>>><<<<><<><<<><<<>>><<>>>><<>>><>><<<>>><>>><<<<>>>><<>>>><><<<<>><>>><<>><<<<>>><<>>>><<<>><<>>>><<<<>>>><<<<>><>><<>>><>>>><<<<>>>><<<>>>><<>>>><<<<>>>><<<>><>>>><<>>><>>><>><><<>>>><<<<>><<<>>>><<<>>><<<<>>>><>>><<<<><<<><<<<>><>><<>><><<>>><<<>>><<><<>>><<<>><<>>>><>>>><>><<<<>>>><<<>><<>>>><<><<>>>><<<>>>><<<<>><<><<<>><<<>>><<>>>><<>><<>>><<>>><>>>><<<>>>><>>><>>>><<<><<<<><<<>>>><<<>>><<<>><>>><><<<><<<>><<>><<<<>><<><<<>>><>>>><<><<<<>>><>>><<<>>><<<>>>><<<<>>>><>>>><<<<>>>><<<<>>><<>><>><<>><<<>><>><<><<<<><<<<><>><<<>>><<<>><<<>>><<>>><<<<><<<>><<>>>><<>>><<<<>><<<>><<><<>><<>>>><>><><<<>>><<><<<>>>><>>>><>>><>>>><>>>><>>>><>>><<<<>>><<<>><<<<>><<>><<<>>>><<<><><><<><<<<><<<>><><<<<>>>><<<<>>>><>>>><<<<>>><<<>><>>><>><>><<>><<>><<<><<>><<>>><<<>>>><<>>>><>>><<<<>>><>><<<<>>>><<<<>><<>><<><<<<><<>>><<<<>><<<>>><<<>>>><<<<>>><><>>>><<<<>>><><<>>>><<>>>><<<>>><<><<<<>>><<>>><><<<><<<>>>><><<<><<<>><<>>><<<>>><<>>><<>>><>><><<<>>>><<><>><>>><<<>><<<<>>>><>>>><<<<><<<>>><>>>><<<>><<><><<<<>>>><<<<>><>>><>><>>>><<<>><<>>>><<<><><<>>><<<<>>><<<>>><<<<>>>><<>>>><>>>><<>>>><<>>><<<<>><<<<>>><<>><<>><>>>><>>><<<<>>><>>><<<>>><<>>><<><><>><<>><>><>>>><>>>><<>>><>>><<<>>><><<<<><>>><<<<>><>>>><<<<><>>>><<<><<<<>><<<>>>><<<<>>><<<>>>><<<>>><<<<><<<<>>><<<>><>>>><<<>>>><<<><<><<><<>><<<<>><<<>>>><<><<<<>>>><>>><>><<>>>><>>>><>><<<>>><<>>>><<<<>>><>>><<<>>>><<<<>>>><>><>><<<<>>>><<>>><>>>><<<><<>>>><<<>><<>>>><><>>>><>><<<>><><<>>>><<<<>>><<>>><<<<>><<>>>><<<<><<>>><<<>><<>><<<<><<<<><>><<<>><>><<<>>><<>>><<<>>><<>>>><<><<<<><<<>>><<<>>><<<>>><<<>>><<>>><<<<>>>><<<<>>>><<>><<>><<>>><>>><<>>><<<<>>>><<>>>><<<<><>>><<<<>><<>>>><<><>><<<<><<<>><>>><>>><<<<><<<>>>><<>>><<<<>>>><>>>><<<<>>>><<<<><<>>><>><>><<><<<<>><<>><<<>>>><>>><<<>>><<<<><<<>><<<<>>>><<<><><<<>>><<<<><<<<>><<<>>><<<<>>>><<<>>>><>>>><<<>>><<<<><><<<>>><<<>><<<<>>>><<<>>><<<>>>><><<>>>><<<<><<<<>>>><<<>><><<><<<>><<<>>>><>><<>>>><>>>><<<>>>><>><<<>>>><<><<>><<<<>><<>><<<><<<<><>>>><<<><<>><<<<>><<<><>><>>>><<<<>>><<<<>>><><<><<><>><<<<><<<<>>>><<<<><<>>><<><<>><<>>><<>><<<>><<<>>>><<><<>>><<<><>>><<><<<<>>>><<>><<<<>><>><<<<><<>>><<<>>>><<<>><<<<>><<<>>><<<<>>><<<<>>><<>><<>><<<<>>>><<<>>><<<>>><>><<<><>><<<<>>><>>>><<>>><>><>>>><<>>><<<>>>><<<<>>><<>><<<<>><<<>>>><<<>><<<>><<>>>><>>>><<<<>>>><<<<>>><<<>><<>>><<<>><<<<>>><<<>>>><><><<>><>><>>><<>><<<<><<<<>>><<>><<<<>>><<<><<>>><<>>>><<<<>>>><<><<<>>><<<<>>><><>>><<<<>>><<>>><<>><<<>>><>>><<>><<<>>>><<>>><<><>>><<<<>>><>>><<<<>>><>>>><>>>><<<<>><>>><<>><<><<>><>><<>>><>><<<<>>><<<<><<<>>>><<<>><>>><<<<>>><><<<><<>>><<>><<<<>><<<<>><>>><<>>><<<<>>>><>>>><<>>><<<<>>><<<<><<<<>>>><<<<>>><<<><<<<>>><<<>>>><<<><<<<>><<<>>><<<><<<>>><<<><<<>>><<>><<<<>>><>>><<<>>><<>>>><<>>>><>><<<<>>><<>>><<<><<<><<<<>>>><<<><<<<>>>><<<>>>><<<>>>><<>>><<<<>><>>>><<>>><<<>>><>><<>><<<>>><<<<>>><<<>>><<<><<<>>>><<>>><><><>>>><<<<>>><<<<>>><><>><<<<>><<<<>>><<>>>><<>>>><<<><>>>><<<>><<<>>>><<<>>><<>><<>>><<<<><>><<>><>>><<<<><<><<>>>><<<<>>><>>><>>><<<>>>><>><<<><<>><<<>>><<<<>>>><<<>><<>>>><<<>><<<<>>>><>><>>>><<<><<<>><<<>>><<<>>>><><<<<>><<<<>><><>>><>><>>><>><>>><><<<>><<<<>>><>>>><<<>>><<<<><<>>><>>>><<<>>><<<<>>>><<><<<>>><<>>><<<>><<<<>>>><<>>>><<<>>>><>>>><<<>><<<>>><<<<>>>><<<<>>><<<<>><<>><<<><><<<<>>>><>><<<>>>><<>><<>>><<><<<><<<<>>><<>>>><><>>>><>>>><<<><<>>><<<<>>>><>><<<>><<<>>>><<<>>><><<><<<>><<<<>><<<>><>><><<<<>><><>>><<<>>><<<>>>><>>>><<<<>>>><>>><>>><<>>><<>>><>>><>><><<>>>><<><<<>><<<<>>>><<<<>>>><<><<>>><<<<><<><>><<<><<>>><>>>><<><<<<>>>><<>>>><<<<><><><>>><<<>><<<<>><<<>>><<<<>>>><<>><<<<>>>><>><<><<>><<>>>><<<<><<>>>><<>>>><<<<>>><>><>><<>><<<<>><>>>><<<>><<>>>><<<<>><>>>><<<><>>>><<>>>><<<>>>><>>><>>>><<>><<>>><<>>><<<<>>><<<<>>><>>><<<>>>><<<<>>><<<>><<<>>><<<<>>><<<<>>>><<<<>>><<<<><<<>><<><>>>><<<<><<>>><<>><<<>><>><<>>>><<>>>><<<>>>><>>>><<<><<<<>><<<>>><>>><>><>>>><><<>>>><>>>><<<>><<>><<>>><<<>>>><>><<<<>><<<<>>>><>>><<<<>><<>><<<><<>>>><<>>><<<<>>><><<><<<><<<>>><<<>><<>>>><<<><>>><<>>><<<>>><<<<>><<><> diff --git a/src/bin/day17_1.rs b/src/bin/day17_1.rs new file mode 100644 index 0000000..be1c3f0 --- /dev/null +++ b/src/bin/day17_1.rs @@ -0,0 +1,8 @@ +use std::fs; + +use aoc2022::day17::process_part_1; + +fn main() { + let file = fs::read_to_string("./inputs/day17.txt").unwrap(); + println!("{}", process_part_1(&file)); +} diff --git a/src/bin/day17_2.rs b/src/bin/day17_2.rs new file mode 100644 index 0000000..aad78b0 --- /dev/null +++ b/src/bin/day17_2.rs @@ -0,0 +1,8 @@ +use std::fs; + +use aoc2022::day17::process_part_2; + +fn main() { + let file = fs::read_to_string("./inputs/day17.txt").unwrap(); + println!("{}", process_part_2(&file)); +} diff --git a/src/day17.rs b/src/day17.rs new file mode 100644 index 0000000..9f2989a --- /dev/null +++ b/src/day17.rs @@ -0,0 +1,224 @@ +use std::collections::HashMap; + +use nom::branch::alt; +use nom::character::complete; +use nom::multi::many1; +use nom::{IResult, Parser}; + +pub fn process_part_1(input: &str) -> usize { + let mut gusts = parse_input(input).unwrap().1.into_iter().cycle(); + let mut templates = all_pieces().into_iter().cycle(); + // Leftmost bit is kept as a wall in the grid, right is done in the right() of piece + let mut grid = [0b1000_0000_u8; 10_000]; + grid[0] = 0b1111_1111; + + (0..2022).fold(0, |z, _| { + let mut piece = Piece { + data: templates.next().unwrap(), + z: z + 4, + }; + + loop { + match gusts.next() { + Some(Gust::Left) => piece.left(&grid), + Some(Gust::Right) => piece.right(&grid), + None => unreachable!(), + } + if !piece.can_move_down(&grid) { + break; + } + piece.down(); + } + + piece.paste(&mut grid); + z.max(piece.max_z()) + }) +} + +pub fn process_part_2(input: &str) -> usize { + let mut gusts = parse_input(input) + .unwrap() + .1 + .into_iter() + .enumerate() + .cycle(); + let mut templates = all_pieces().into_iter().enumerate().cycle(); + let mut grid = [0b1000_0000_u8; 10_000]; + grid[0] = 0b1111_1111; + + let mut cache = HashMap::new(); + let mut i = 0; + let mut skipped = 0; + let mut z = 0; + let iterations = 1_000_000_000_000usize; + + while i < iterations { + let (piece_id, template) = templates.next().unwrap(); + let mut piece = Piece { + data: template, + z: z + 4, + }; + + let mut gust_id; + loop { + let (i, gust) = gusts.next().unwrap(); + gust_id = i; + match gust { + Gust::Left => piece.left(&grid), + Gust::Right => piece.right(&grid), + } + if !piece.can_move_down(&grid) { + break; + } + piece.down(); + } + + piece.paste(&mut grid); + + z = z.max(piece.max_z()); + + if z > 64 && skipped == 0 { + let key = HashKey { + piece_id, + gust_id, + grid: grid[z - 63..=z].try_into().unwrap(), + }; + if let Some((previous_z, previous_i)) = cache.insert(key, (z, i)) { + // We got a cache hit! Let's compare the two states to know the period. + let height_diff = z - previous_z; + let iterations_diff = i - previous_i; + // Now we know how many periods (cycles) we can skip without affecting the state/repetition + let skip_repeats = (iterations - i) / iterations_diff; + let skip_iterations = skip_repeats * iterations_diff; + let skip_height = skip_repeats * height_diff; + // We fast-forward our piece counter + i += skip_iterations; + // We record how much height we skipped, which we will add to the final result to get the real value + skipped = skip_height; + } + } + + i += 1; + } + z + skipped +} + +#[derive(Hash, PartialEq, Eq)] +struct HashKey { + piece_id: usize, + gust_id: usize, + grid: [u8; 64], +} + +#[derive(Debug, Copy, Clone)] +enum Gust { + Left, + Right, +} + +fn parse_input(input: &str) -> IResult<&str, Vec> { + many1( + alt((complete::char('<'), complete::char('>'))).map(|v| match v { + '<' => Gust::Left, + '>' => Gust::Right, + _ => unreachable!(), + }), + )(input) +} + +struct Piece { + data: [u8; 4], + z: usize, +} + +impl Piece { + fn left(&mut self, grid: &[u8]) { + // Only the rows we occupy are interesting + let grid = &grid[self.z..self.z + 4]; + let collision = grid + .iter() + .zip(self.data) + .any(|(grid, piece)| (piece << 1 & grid) > 0); + + if collision { + return; + } + + for row in &mut self.data { + *row <<= 1; + } + } + + fn right(&mut self, grid: &[u8]) { + // Only the rows we occupy are interesting + let grid = &grid[self.z..self.z + 4]; + let collision = grid + .iter() + .zip(self.data) + .any(|(grid, piece)| (piece.trailing_ones() as u8 | (piece >> 1 & grid)) > 0); + + if collision { + return; + } + + for row in &mut self.data { + *row >>= 1; + } + } + + fn can_move_down(&self, grid: &[u8]) -> bool { + let grid = &grid[self.z - 1..=self.z]; + !grid + .iter() + .zip(self.data) + .any(|(grid, piece)| (piece & grid) > 0) + } + + fn down(&mut self) { + self.z -= 1; + } + + fn paste(&self, grid: &mut [u8]) { + for (grid, piece) in grid[self.z..self.z + 4].iter_mut().zip(self.data) { + *grid |= piece + } + } + + fn height(&self) -> usize { + self.data + .iter() + .take_while(|row| row.count_ones() > 0) + .count() + } + + fn max_z(&self) -> usize { + self.z + self.height() - 1 + } +} + +fn all_pieces() -> [[u8; 4]; 5] { + [ + [0b11110, 0b0, 0b0, 0b0], + [0b1000, 0b11100, 0b1000, 0b0], + [0b11100, 0b100, 0b100, 0b0], + [0b10000; 4], + [0b11000, 0b11000, 0b0, 0b0], + ] +} + +#[cfg(test)] +mod tests { + use super::*; + + const INPUT: &str = ">>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>"; + + #[test] + fn day1() { + assert_eq!(process_part_1(INPUT), 3068); + } + + #[test] + fn day2() { + assert_eq!(process_part_2(INPUT), 1_514_285_714_288); + } +} diff --git a/src/lib.rs b/src/lib.rs index 2882a36..614b966 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,3 +17,4 @@ pub mod day13; pub mod day14; pub mod day15; pub mod day16; +pub mod day17;