use nom::{ character::complete::{line_ending, one_of}, combinator::map_res, multi::{many1, separated_list1}, IResult, }; use std::fs; fn main() -> Result<(), Box> { let input = fs::read_to_string("inputs/day_11.txt")?; let squid_grid = parse_squid_grid(&input).unwrap().1; { let mut squid_grid = squid_grid.clone(); let mut flashes_on_100 = 0; for _ in 0..100 { flashes_on_100 += squid_grid.flash(); } dbg!(flashes_on_100); } { let mut squid_grid = squid_grid.clone(); let sync_time = std::iter::repeat_with(|| squid_grid.flash()) .position(|flashes| flashes == 100) .map(|x| x + 1); dbg!(sync_time); } Ok(()) } #[derive(Debug, Clone)] struct Squid { energy: u8, has_flashed: bool, } impl Squid { fn should_flash(&self) -> bool { self.energy > 9 && !self.has_flashed } fn reset(&mut self) { self.energy = 0; self.has_flashed = false; } } #[derive(Debug, Clone)] struct SquidGrid { squids: [[Squid; 10]; 10], } impl SquidGrid { fn flash(&mut self) -> usize { for y in 0..10 { for x in 0..10 { self.squids[y][x].energy += 1; } } let mut any_new_flashes = true; while any_new_flashes { any_new_flashes = false; for y in 0..10 { for x in 0..10 { if self.squids[y][x].should_flash() { any_new_flashes = true; self.squids[y][x].has_flashed = true; if y > 0 && x > 0 { self.squids[y - 1][x - 1].energy += 1; } if y > 0 { self.squids[y - 1][x].energy += 1; } if y > 0 && x < 9 { self.squids[y - 1][x + 1].energy += 1; } if x > 0 { self.squids[y][x - 1].energy += 1; } if x < 9 { self.squids[y][x + 1].energy += 1; } if y < 9 && x > 0 { self.squids[y + 1][x - 1].energy += 1; } if y < 9 { self.squids[y + 1][x].energy += 1; } if y < 9 && x < 9 { self.squids[y + 1][x + 1].energy += 1; } } } } } let mut flashes = 0; for y in 0..10 { for x in 0..10 { if self.squids[y][x].has_flashed { self.squids[y][x].reset(); flashes += 1; } } } flashes } } fn parse_squid_grid(input: &str) -> IResult<&str, SquidGrid> { map_res(separated_list1(line_ending, parse_squid_row), |squids| { squids.try_into().map(|squids| SquidGrid { squids }) })(input) } fn parse_squid_row(input: &str) -> IResult<&str, [Squid; 10]> { map_res(many1(parse_squid), |squids| squids.try_into())(input) } fn parse_squid(input: &str) -> IResult<&str, Squid> { map_res(one_of("0123456789"), |digit| { digit.to_string().parse().map(|energy| Squid { energy, has_flashed: false, }) })(input) }