diff --git a/input/day11.txt b/input/day11.txt new file mode 100644 index 0000000..db2a113 --- /dev/null +++ b/input/day11.txt @@ -0,0 +1,10 @@ +1553421288 +5255384882 +1224315732 +4258242274 +1658564216 +6872651182 +5775552238 +5622545172 +8766672318 +2178374835 diff --git a/src/day11.rs b/src/day11.rs new file mode 100644 index 0000000..06477c4 --- /dev/null +++ b/src/day11.rs @@ -0,0 +1,148 @@ +use ansi_term::{Color, Style}; +use std::collections::{HashSet, VecDeque}; +use std::fmt::{Debug, Formatter}; +use std::ops::RangeInclusive; + +pub fn day11() { + // let input = r#" + // 11111 + // 19991 + // 19191 + // 19991 + // 11111 + // "#; + + // let grid: Grid<5> = input.into(); + // dbg!(&grid); + // dbg!(&grid.step()); + // dbg!(&grid.step().step()); + + // let input = r#" + // 5483143223 + // 2745854711 + // 5264556173 + // 6141336146 + // 6357385478 + // 4167524645 + // 2176841721 + // 6882881134 + // 4846848554 + // 5283751526 + // "#; + let input = include_str!("../input/day11.txt"); + + let mut grid: Grid<10> = input.into(); + let mut total_flashes = 0; + + println!("{:?}", grid); + + for step in 0..100 { + let (new, flashed) = grid.step(); + // println!("after step: {}, new grid: {:?}", step + 1, new); + grid = new; + total_flashes += flashed; + } + + println!("grid: {:?}, total flashes: {}", grid, total_flashes); + + let mut grid2: Grid<10> = input.into(); + let mut step = 0; + loop { + step += 1; + let (new, flashed) = grid2.step(); + grid2 = new; + if flashed == 100 { + break; + } + } + println!("grid: {:?}, after step: {}", grid2, step); +} + +struct Grid { + grid: [[u32; N]; N], +} + +impl Debug for Grid { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "\n").expect("write"); + for row in 0..N { + for col in 0..N { + let mut style = Style::new(); + if self.grid[row][col] == 0 { + style = Color::White.bold(); + } + write!( + f, + "{}{}{}", + style.prefix(), + self.grid[row][col], + style.suffix() + ) + .expect("write"); + } + write!(f, "\n").expect("write"); + } + Ok(()) + } +} + +impl From<&str> for Grid { + fn from(s: &str) -> Self { + let mut grid = [[0; N]; N]; + for (row, line) in s.trim().lines().enumerate() { + if row >= N { + panic!("invalid grid size"); + } + for (col, c) in line.trim().chars().enumerate() { + grid[row][col] = c.to_digit(10).unwrap(); + } + } + Self { grid } + } +} + +impl Grid { + fn step(&self) -> (Grid, usize) { + let mut new_grid = [[0; N]; N]; + + // increment all + for row in 0..N { + for col in 0..N { + new_grid[row][col] = self.grid[row][col] + 1; + } + } + + let mut to_flash = (0..N) + .flat_map(|row| (0..N).map(move |col| (row, col))) + .filter(|&(row, col)| new_grid[row][col] > 9) + .collect::>(); + let mut already_flashed: HashSet<(usize, usize)> = HashSet::new(); + while let Some((row, col)) = to_flash.pop_front() { + if already_flashed.contains(&(row, col)) { + continue; + } + + already_flashed.insert((row, col)); + for r in adjacent(row, N) { + for c in adjacent(col, N) { + new_grid[r][c] += 1; + if new_grid[r][c] > 9 && !already_flashed.contains(&(r, c)) { + to_flash.push_back((r, c)); + } + } + } + } + + for &(row, col) in already_flashed.iter() { + new_grid[row][col] = 0; + } + + (Self { grid: new_grid }, already_flashed.len()) + } +} + +fn adjacent(n: usize, max: usize) -> RangeInclusive { + let min = if n > 0 { n - 1 } else { n }; + let max = if n < max - 1 { n + 1 } else { n }; + min..=max +}