From ff8c6f71565c547965acf3e1b7a105f0db85ac66 Mon Sep 17 00:00:00 2001 From: Glenn Griffin Date: Fri, 11 Dec 2020 10:19:41 -0800 Subject: [PATCH] day11 --- input/2020/day11.txt | 93 +++++++++++++++ src/day11.rs | 275 +++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 +- 3 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 input/2020/day11.txt create mode 100644 src/day11.rs diff --git a/input/2020/day11.txt b/input/2020/day11.txt new file mode 100644 index 0000000..60459f2 --- /dev/null +++ b/input/2020/day11.txt @@ -0,0 +1,93 @@ +LLLLLLLLL.L.LLLL.LLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLL..LLLLLL.LLLLLLLL.LLLLL.LL.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLL..LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLL..LL.LLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLL..LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLL.LLLLL.LLLLLLLLLL..LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLL.LLLL.LLLLLLLLLL..LLLL.L.LLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LL.LLLLLL.LLLLLL.LLLLLLLLLLL.LLLLLLLLLL.L.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LL.L.LLLL.L.LLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL +......L.L.L....LL.L.L..L.L..LL...L......LL..L.....L.LL.LLLL.LL.L..LL........L..LL.LLL.L..L.LL.L..L +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLL.L.LLLLLLLLLLLLLL.LLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLL.L.LL.LLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLL.LLL.LLLLL.LL.LLLLLLLLL.LLLLLL.LLL..LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.L.LLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLL.LL.LLLLL.LLLLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLLLLL.L...LLLLLLLL +LLLLLLLLLLLLLLLL.LLLL.LLLL..LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLL.L +LLLLLLLL..LL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLL.LLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL +LLLLLLLL.LLL.LLLLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLL.LLLL.LL.LLLLLLLLLLLLLLLLLLLL +LL..L.....L..L.L...LL...........LLL.L.L..L.L.....LL....LL....L...L...L..LL.L...LL.LL.LLL.L.L.LL.L. +LLLLLLL.L.LLLLLL.LLL.LLLLLLLLLLLLLLLLLL.LLLL.LL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLL.LL.LLLL.LLLLLLLL.LLLLLLLL.LLLLLL.LL.LLLL.LLLLLL.LLLLLLL.LLLLLLLLLLLLLLLL.LLL.LLLLLLL +.LLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLL.LL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLL.LLLLL.LLL.LLLLL.LLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.L.LL.LLLLLLL.LLLLLLLLL.LLLLLLL.LLLLLLLLLL +LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL..LLL.LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.L.LL.LLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.LL.LLL.LLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL..LLLLLLL.LLLL.LLLL.LLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL +.L..L..L..........L...L.LL..L...LL....LL..LL..L...L.LL.L.L..LLLL..L.L....L.......LL........L.L..L. +LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLL.LLLL.LL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLL.LLLLL.LLLLLLLL.LLLLLL.LL.LLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLL.L.LLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL..LLL.LLLL.LLLLLLLLLLL.LLL.LLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLL.LL.LL.LLL.LLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLL.LL.LLLLLLLLLLLL +LLLLLLL.L.LLL..LL.LLLLLLLLLLLL.LLLLLLLLL.LLL.LLLL.LLLLL..LLLL..LLLL.L.LLLLLLL.LLLLLL.LL.LLLLLLLLLL +L.LL...L..L..L.....L...L..LL...L..LL.L.....LL.LL.L...LL.LL...L....LLL.L..LL.L.L.LL..L..LL.L.L.L..L +LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLL..LLLLLL.LLLL.LLLLLLLL.LL.LLLLL.LLLL.LL.L.LLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLL.L.LLL.LLLL +LLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLLLLLL..LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL..LLLLLLLLLLLLLLLLLLLLLLLLLL.L.LLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL..LLL.LL..L.L.LLL.LLL.LLLLLLLLL.LLLLLLLLLL +L...LLL.L......LL....L.......L..L.LLL..LL.LL.L.....LL.LL.L....L.L....LL....L....LL...L.L.....L.... +LLLLLLLLL.LLLLLL.L.LL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LL.LLLLLLLL.LLL.LLLLLLLLL..LL.LLLL.LLLLLLLLLLL..L.L.LLLLLLL.LL.LLLL.LLLLLLLLL.LLLLLLLLLL +....L.L..L.L...L....L..L...L.LLL...L..LL.L..L.LL.L....L.................L...LL.LL......L...L...LL. +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLL.LLLLLL..LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLL.LLLLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.L.LL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LL.LLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL +.....L.LLLL.L.........LL.L..L...LL..LLL..L......LLL.....L.......L.LL.L.L........L...LLLLLL.L..LLL. +LLLL.LLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLLLL.LLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.L.LLLLLL.LLLLLLLLLLLLL.LL.L.LLLLLLL.LLL.L.LLLLLLLLLLLLL.LLLLLL.LL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLL..LLLLLLLLLL.LLLLL.L.LLLLLLL.LLLLLLLLL.LLLLL.LLLL +LLLL.....L.L...L.....L..L.L..L......LL..L...LL...L.LLL.L.L..L....L......LL.LL.L..L.L....L...LL..LL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLL.L +LLLLLLLLL.L.LLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLL.LL.LLL..LLLLLLLLLLL.L.LLLLLLLLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLLL.LL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLL.LL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LL.L..LLL.LLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLL..LLLLLLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLL.L.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLL.L.LL.LLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLL.L.LLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLL.LL.LLLLLLLLLLLLLLLLLLLL +..LL.LL...L....LLLLL.....L.L..LL.L...LLLL.............L..L.LLL..........L.L...LL..LL.....LL....... +LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLL.LL.LLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLL..LLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLL.LL.LLLL.LLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLL.LLLLLLL.LLL.LLLLL.LLL.LLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLLLL.LLLL.LLLL.LLLLLLL.LLL.LL..LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LL.LLL.LLLL.LLLL.LLL.LLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLL..LLLLLLLLLL +..LLLL.LLL...LLLLL..........L...L......L..LL.....L..L..L..L.L..L..L.L..L.......L..L....LL.L.L.L.L. +LLLLLL.LL.LLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLLLLLLL.LLL.LL.LLLL.LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLL.L.LLLLLLLLLLL.LLLLLLLLLLLLLLLLL.LLL..LLLL..LLLLLLLLLLLLLLLLLLLLLLLLLL.LLL.LLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLL.LLL.LLLLLLLLLLLLL.LLLL.LLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLL..LLLLLLLLL +LLLLLLLLL.LLLLLL.LLLLLLLLLLLLL.LLLLLLLL.LLLL.LLL..LLLL.LLL.LL.LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLL.LL.LLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLL.LLLLLLLLLL +LLLLLLLLLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLL.LLLL.LLL..LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL...LLLLLLLLL +L.LLLLLLL.LLLLLLL.LLL.LLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLL.L +LLLLLLL.L.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLL.LLLLLL..LLLLLLLLLL..LLLLLLL.LLLLLLLLLLLLLLLLLLLL +.LL...............L..L.L.LL...L.LL.....LL..L.LL.L.L...L.......L..L.LL..L.L...LL...L............... +LLLLLLLLL.LLLLLL..LLL.LLLLLLLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLL.LLLL.LLLLLLLLLLLLL.LLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.L.LLLLLLLLLLL.LL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLL +LLL.LLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLL.L.LLL.LLLLLL.LLL.LLLL.L.LLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLL.LL.LLL.LLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL +LLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LL.LLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLLL.LLLLLLL.LLLLLLLLL.LLLLLLLLLL +L.LLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLL.LLLL.LLLL.LLLLLL.LLLL.LLLLLL..LLLLLLL.LLLLLLLLL.LLLLLLLLLL diff --git a/src/day11.rs b/src/day11.rs new file mode 100644 index 0000000..f1bf4db --- /dev/null +++ b/src/day11.rs @@ -0,0 +1,275 @@ +use aoc_runner_derive::aoc; +use std::fmt; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(u8)] +enum GridSquare { + Empty = b'L', + Occupied = b'#', + Floor = b'.', +} + +impl GridSquare { + fn from_u8(b: u8) -> Option { + Some(match b { + b'L' => GridSquare::Empty, + b'#' => GridSquare::Occupied, + b'.' => GridSquare::Floor, + _ => return None, + }) + } + fn into_u8(self) -> u8 { + match self { + GridSquare::Empty => b'L', + GridSquare::Occupied => b'#', + GridSquare::Floor => b'.', + } + } +} + +impl fmt::Display for GridSquare { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.into_u8() as char) + } +} + +#[derive(Debug, Copy, Clone)] +struct GridIdx(usize); + +#[derive(Debug, PartialEq, Eq)] +struct Grid { + row_len: usize, + grid: Vec, +} + +impl Grid { + fn parse(input: &str) -> Option { + let row_len = input.find('\n')?; + let grid = input + .bytes() + .filter(|&b| b != b'\n') + .map(|b| GridSquare::from_u8(b)) + .collect::>>()?; + Some(Grid { row_len, grid }) + } + + fn new(grid: Vec, row_len: usize) -> Grid { + if grid.len() % row_len != 0 { + panic!("invalid grid"); + } + Grid { grid, row_len } + } + + fn enumerate(&self) -> impl Iterator + '_ { + self.grid + .iter() + .copied() + .enumerate() + .map(|(idx, square)| (GridIdx(idx), square)) + } + + fn is_occupied(&self, idx: usize) -> bool { + self.grid[idx] == GridSquare::Occupied + } + + fn num_adjacent_occupied(&self, idx: GridIdx) -> usize { + let mut total = 0; + let col = idx.0 % self.row_len; + + // Add row above idx if it exists. + if self.row_len < idx.0 { + let above_idx = idx.0 - self.row_len; + if col > 0 && self.is_occupied(above_idx - 1) { + total += 1; + } + if self.is_occupied(above_idx) { + total += 1; + } + if col < self.row_len - 1 && self.is_occupied(above_idx + 1) { + total += 1; + } + } + + // Add left and right if they exist. + if col > 0 && self.is_occupied(idx.0 - 1) { + total += 1; + } + if col < self.row_len - 1 && self.is_occupied(idx.0 + 1) { + total += 1; + } + + // Add row below if it exists. + let below_idx = idx.0 + self.row_len; + if below_idx < self.grid.len() { + if col > 0 && self.is_occupied(below_idx - 1) { + total += 1; + } + if self.is_occupied(below_idx) { + total += 1; + } + if col < self.row_len - 1 && self.is_occupied(below_idx + 1) { + total += 1; + } + } + total + } + + fn num_visible_occupied(&self, idx: GridIdx) -> usize { + let mut total = 0; + for &(x_step, y_step) in &[ + (-1, -1), + (-1, 0), + (-1, 1), + (0, -1), + (0, 1), + (1, -1), + (1, 0), + (1, 1), + ] { + total += GridIter::new(self, idx, x_step, y_step) + .find_map(|idx| match &self.grid[idx.0] { + GridSquare::Empty => Some(0), + GridSquare::Occupied => Some(1), + GridSquare::Floor => None, + }) + .unwrap_or(0); + } + total + } +} + +impl fmt::Display for Grid { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for line in self.grid.chunks_exact(self.row_len) { + for square in line { + write!(f, "{}", square)?; + } + write!(f, "\n")?; + } + Ok(()) + } +} + +#[aoc(day11, part1)] +fn solve_d11_p1(input: &str) -> usize { + fn next_grid(orig: &Grid) -> Grid { + let new_grid: Vec = orig + .enumerate() + .map(|(grid_idx, grid_square)| match grid_square { + GridSquare::Empty => { + let occupied = orig.num_adjacent_occupied(grid_idx); + if occupied == 0 { + GridSquare::Occupied + } else { + GridSquare::Empty + } + } + GridSquare::Occupied => { + let occupied = orig.num_adjacent_occupied(grid_idx); + if occupied >= 4 { + GridSquare::Empty + } else { + GridSquare::Occupied + } + } + GridSquare::Floor => GridSquare::Floor, + }) + .collect(); + Grid::new(new_grid, orig.row_len) + } + let mut grid = Grid::parse(input).unwrap(); + let stable_grid = loop { + let next = next_grid(&grid); + if next == grid { + break next; + } + grid = next; + }; + stable_grid + .enumerate() + .filter(|&(_idx, square)| square == GridSquare::Occupied) + .count() +} + +#[derive(Debug)] +struct GridIter { + x: isize, + y: isize, + x_step: isize, + y_step: isize, + num_cols: usize, + num_rows: usize, +} +impl GridIter { + fn new(grid: &Grid, idx: GridIdx, x_step: isize, y_step: isize) -> Self { + let num_cols = grid.row_len; + let num_rows = grid.grid.len() / num_cols; + let x = (idx.0 % num_cols) as isize; + let y = (idx.0 / num_cols) as isize; + GridIter { + x, + y, + x_step, + y_step, + num_cols, + num_rows, + } + } +} + +impl Iterator for GridIter { + type Item = GridIdx; + + fn next(&mut self) -> Option { + self.x += self.x_step; + self.y += self.y_step; + if self.x < 0 || self.x >= self.num_cols as isize { + return None; + } + if self.y < 0 || self.y >= self.num_rows as isize { + return None; + } + Some(GridIdx(self.y as usize * self.num_cols + self.x as usize)) + } +} + +#[aoc(day11, part2)] +fn solve_d11_p2(input: &str) -> usize { + fn next_grid(orig: &Grid) -> Grid { + let new_grid: Vec = orig + .enumerate() + .map(|(grid_idx, grid_square)| match grid_square { + GridSquare::Empty => { + let occupied = orig.num_visible_occupied(grid_idx); + if occupied == 0 { + GridSquare::Occupied + } else { + GridSquare::Empty + } + } + GridSquare::Occupied => { + let occupied = orig.num_visible_occupied(grid_idx); + if occupied >= 5 { + GridSquare::Empty + } else { + GridSquare::Occupied + } + } + GridSquare::Floor => GridSquare::Floor, + }) + .collect(); + Grid::new(new_grid, orig.row_len) + } + let mut grid = Grid::parse(input).unwrap(); + let stable_grid = loop { + let next = next_grid(&grid); + if next == grid { + break next; + } + grid = next; + }; + stable_grid + .enumerate() + .filter(|&(_idx, square)| square == GridSquare::Occupied) + .count() +} diff --git a/src/lib.rs b/src/lib.rs index f61e4e5..9aa3dcd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ pub mod day1; +pub mod day10; +pub mod day11; pub mod day2; pub mod day3; pub mod day4; @@ -7,6 +9,5 @@ pub mod day6; pub mod day7; pub mod day8; pub mod day9; -pub mod day10; aoc_runner_derive::aoc_lib! { year = 2020 }