use std::collections::HashMap; use crate::Day; type FlashMap = HashMap<(i32, i32), i32>; pub struct Day11(FlashMap); impl Day for Day11 { fn init(content: String) -> anyhow::Result { let mut map = HashMap::new(); for (y, n) in content.lines().enumerate() { for (x, char) in n.chars().enumerate() { map.insert((x as i32, y as i32), char.to_string().parse::()?); } } Ok(Self(map)) } fn part1(&self) -> anyhow::Result { let mut hm = self.0.clone(); let mut flashes = 0; for _ in 0..100 { hm.iter_mut().for_each(|(_, x)| *x += 1); let mut flashing = get_flashes(&hm); let mut flashed = vec![]; do_flash(&mut hm, &mut flashing, &mut flashed); let flashing = get_flashes(&hm); for f in &flashing { if let Some(entry) = hm.get_mut(f) { *entry = 0; } } flashes += flashing.len(); } Ok(format!("{}", flashes)) } fn part2(&self) -> anyhow::Result { let mut hm = self.0.clone(); for num in 0..1000 { hm.iter_mut().for_each(|(_, x)| *x += 1); let mut flashing = get_flashes(&hm); let mut flashed = vec![]; do_flash(&mut hm, &mut flashing, &mut flashed); if flashed.len() == 100 { return Ok(format!("{}", num + 1)); } let flashing = get_flashes(&hm); for f in &flashing { if let Some(entry) = hm.get_mut(f) { *entry = 0; } } } Err(anyhow::Error::msg("It did not flash 100 times :(")) } } fn get_flashes(hm: &FlashMap) -> Vec<(i32, i32)> { hm.iter().filter(|(_, &x)| x > 9).map(|(&p, _)| p).collect::>() } fn do_flash(mut hm: &mut FlashMap, mut flashing: &mut Vec<(i32, i32)>, mut flashed: &mut Vec<(i32, i32)>) { if let Some((x, y)) = flashing.pop() { flashed.push((x, y)); for xn in (x - 1)..=(x + 1) { for yn in (y - 1)..=(y + 1) { if let Some(e) = hm.get_mut(&(xn, yn)) { *e += 1; if *e > 9 && !flashed.contains(&(xn, yn)) && !flashing.contains(&(xn, yn)) { flashing.push((xn, yn)) } } } } do_flash(&mut hm, &mut flashing, &mut flashed) } } #[allow(unused)] fn print_flashes(map: &FlashMap, x_max: i32, y_max: i32) { let mut v: Vec> = Vec::new(); for y in 0..y_max { let mut col = Vec::new(); for x in 0..x_max { col.push(*map.get(&(x, y)).unwrap()); } v.push(col); } for line in v { for ch in line { print!("{}", ch) } println!() } println!() } #[cfg(test)] mod tests { use crate::{Day, day_tests}; use crate::day11::Day11; const INPUT: &str = r"5483143223 2745854711 5264556173 6141336146 6357385478 4167524645 2176841721 6882881134 4846848554 5283751526"; #[test] fn part1_test() -> anyhow::Result<()> { let d = Day11::init(INPUT.to_string())?; assert_eq!("1656", d.part1()?); Ok(()) } #[test] fn part2_test() -> anyhow::Result<()> { let d = Day11::init(INPUT.to_string())?; assert_eq!("195", d.part2()?); Ok(()) } day_tests!(Day11, "11", "1647", "348"); }