1
0
aoc-2021/src/day11.rs

172 lines
4.0 KiB
Rust

use arrayvec::ArrayVec;
pub fn parse_input(input: &str) -> [[u32; 10]; 10] {
input.lines()
.map(|s| s.chars()
.map(|s| s.to_digit(10).unwrap())
.collect::<ArrayVec<u32, 10>>()
.into_inner()
.unwrap())
.collect::<ArrayVec<[u32; 10], 10>>()
.into_inner()
.unwrap()
}
fn display_grid(grid: &[[u32; 10]; 10]) {
for i in 0..grid.len() {
for j in 0..grid[i].len() {
print!("{:X}", grid[i][j]);
}
print!("\n");
}
print!("\n");
}
fn bump_energy(grid: &mut [[u32; 10]; 10]) {
for i in 0..grid.len() {
for j in 0..grid[i].len() {
grid[i][j] += 1;
}
}
}
fn bump_energy_around(grid: &mut [[u32; 10]; 10], i: usize, j: usize) {
if j > 0 {
grid[i+0][j-1] += 1;
}
if j < 9 {
grid[i+0][j+1] += 1;
}
if i > 0 {
grid[i-1][j+0] += 1;
}
if i < 9 {
grid[i+1][j+0] += 1;
}
if i > 0 && j > 0 {
grid[i-1][j-1] += 1;
}
if i < 9 && j > 0 {
grid[i+1][j-1] += 1;
}
if i > 0 && j < 9 {
grid[i-1][j+1] += 1;
}
if i < 9 && j < 9 {
grid[i+1][j+1] += 1;
}
}
fn perform_flashes(grid: &mut [[u32; 10]; 10]) -> u32 {
let mut flashes = 0;
let mut has_flashed: [[bool; 10]; 10] = [[false; 10]; 10];
let mut anyone_flashed = true;
while anyone_flashed {
anyone_flashed = false;
for i in 0..grid.len() {
for j in 0..grid[i].len() {
if grid[i][j] > 9 && !has_flashed[i][j] {
flashes += 1;
has_flashed[i][j] = true;
anyone_flashed = true;
bump_energy_around(grid, i, j);
}
}
}
}
return flashes;
}
fn reset_energy(grid: &mut [[u32; 10]; 10]) {
for i in 0..grid.len() {
for j in 0..grid[i].len() {
if grid[i][j] > 9 {
grid[i][j] = 0;
}
}
}
}
fn do_step(grid: &mut [[u32; 10]; 10]) -> u32 {
bump_energy(grid);
let flashes = perform_flashes(grid);
reset_energy(grid);
return flashes;
}
fn has_all_zeros(grid: &[[u32; 10]; 10]) -> bool {
for i in 0..grid.len() {
for j in 0..grid[i].len() {
if grid[i][j] != 0 {
return false;
}
}
}
return true;
}
pub fn part1(grid: &[[u32; 10]; 10]) -> u32 {
let mut flashes = 0;
let mut active_grid = grid.clone();
for _ in 0..100 {
flashes += do_step(&mut active_grid);
}
return flashes;
}
pub fn part2(grid: &[[u32; 10]; 10]) -> u32 {
let mut active_grid = grid.clone();
let mut step = 0;
while !has_all_zeros(&active_grid) {
do_step(&mut active_grid);
step += 1;
}
return step;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn part1_example() {
let input = [
[5, 4, 8, 3, 1, 4, 3, 2, 2, 3],
[2, 7, 4, 5, 8, 5, 4, 7, 1, 1],
[5, 2, 6, 4, 5, 5, 6, 1, 7, 3],
[6, 1, 4, 1, 3, 3, 6, 1, 4, 6],
[6, 3, 5, 7, 3, 8, 5, 4, 7, 8],
[4, 1, 6, 7, 5, 2, 4, 6, 4, 5],
[2, 1, 7, 6, 8, 4, 1, 7, 2, 1],
[6, 8, 8, 2, 8, 8, 1, 1, 3, 4],
[4, 8, 4, 6, 8, 4, 8, 5, 5, 4],
[5, 2, 8, 3, 7, 5, 1, 5, 2, 6]
];
let result = part1(&input);
assert_eq!(result, 1656);
}
#[test]
fn part2_example() {
let input = [
[5, 4, 8, 3, 1, 4, 3, 2, 2, 3],
[2, 7, 4, 5, 8, 5, 4, 7, 1, 1],
[5, 2, 6, 4, 5, 5, 6, 1, 7, 3],
[6, 1, 4, 1, 3, 3, 6, 1, 4, 6],
[6, 3, 5, 7, 3, 8, 5, 4, 7, 8],
[4, 1, 6, 7, 5, 2, 4, 6, 4, 5],
[2, 1, 7, 6, 8, 4, 1, 7, 2, 1],
[6, 8, 8, 2, 8, 8, 1, 1, 3, 4],
[4, 8, 4, 6, 8, 4, 8, 5, 5, 4],
[5, 2, 8, 3, 7, 5, 1, 5, 2, 6]
];
let result = part2(&input);
assert_eq!(result, 195);
}
}