diff --git a/2021/inputs/11.txt b/2021/inputs/11.txt new file mode 100644 index 0000000..efb0e67 --- /dev/null +++ b/2021/inputs/11.txt @@ -0,0 +1,10 @@ +5651341452 +1381541252 +1878435224 +6814831535 +3883547383 +6473548464 +1885833658 +3732584752 +1881546128 +5121717776 diff --git a/2021/src/day11.rs b/2021/src/day11.rs index 113ba49..e1e4062 100644 --- a/2021/src/day11.rs +++ b/2021/src/day11.rs @@ -1,9 +1,114 @@ use std::io::Read; -pub fn part1(_input: &mut dyn Read) -> String { - todo!() +fn read_grid<'a>(input: &'_ mut dyn Read, buffer: &'a mut Vec) -> Vec<&'a mut [u8]> { + input.read_to_end(buffer).unwrap(); + + let mut grid: Vec<&mut [u8]> = buffer.split_mut(|&b| b == b'\n').collect(); + + grid.iter_mut() + .flat_map(|line| line.iter_mut()) + .for_each(|b| *b -= b'0'); + + grid } -pub fn part2(_input: &mut dyn Read) -> String { - todo!() +fn advance(grid: &mut [&mut [u8]], todo: &mut Vec<(i8, i8)>) -> usize { + let mut flashes = 0; + + grid.iter_mut() + .enumerate() + .flat_map(|(y, line)| { + line.iter_mut() + .enumerate() + .map(move |(x, value)| (x, y, value)) + }) + .for_each(|(x, y, value)| { + *value += 1; + if *value > 9 { + todo.push((x as i8, y as i8)); + } + }); + + while let Some((x, y)) = todo.pop() { + flashes += 1; + + for dy in -1..=1 { + for dx in -1..=1 { + if dx == 0 && dy == 0 { + continue; + } + + let nx = usize::try_from(x + dx); + let ny = usize::try_from(y + dy); + + if let (Ok(nx), Ok(ny)) = (nx, ny) { + if let Some(value) = grid.get_mut(ny).and_then(|line| line.get_mut(nx)) { + *value += 1; + if *value == 10 { + todo.push((nx as i8, ny as i8)); + } + } + } + } + } + } + + grid.iter_mut() + .flat_map(|line| line.iter_mut()) + .filter(|b| **b > 9) + .for_each(|b| *b = 0); + + flashes +} + +pub fn part1(input: &mut dyn Read) -> String { + let mut buffer = Vec::new(); + + let mut grid = read_grid(input, &mut buffer); + let mut todo = Vec::new(); + + (0..100) + .map(|_| advance(&mut grid, &mut todo)) + .sum::() + .to_string() +} + +pub fn part2(input: &mut dyn Read) -> String { + let mut buffer = Vec::new(); + + let mut grid = read_grid(input, &mut buffer); + let mut todo = Vec::new(); + + let target = grid.iter().map(|line| line.len()).sum(); + + (1..) + .find_map(|step| { + let flashes = advance(&mut grid, &mut todo); + if flashes == target { + Some(step) + } else { + None + } + }) + .unwrap() + .to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::test_implementation; + + const SAMPLE: &[u8] = include_bytes!("samples/11.txt"); + + #[test] + fn sample_part1() { + test_implementation(part1, SAMPLE, 1656); + } + + #[test] + fn sample_part2() { + test_implementation(part2, SAMPLE, 195); + } } diff --git a/2021/src/samples/11.txt b/2021/src/samples/11.txt new file mode 100644 index 0000000..03743f6 --- /dev/null +++ b/2021/src/samples/11.txt @@ -0,0 +1,10 @@ +5483143223 +2745854711 +5264556173 +6141336146 +6357385478 +4167524645 +2176841721 +6882881134 +4846848554 +5283751526