---cargo --- static CONTENT: &'static str = include_str!("./inputs/04_1.txt"); static GRID_OFFSETS: [(isize, isize); 8] = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]; #[derive(Debug, PartialEq, Clone)] enum Cell { Empty, PRoll, } fn main() { let mut grid: Vec<_> = CONTENT.lines().map(|l| l.trim()).filter(|l| !l.is_empty()).map(|l| { l.chars().map(|c| match c { '.' => Cell::Empty, '@' => Cell::PRoll, other => unreachable!("Unexpected Input {:?}", other), }).collect::>() }).collect(); let mut result = 0; loop { let mut to_remove = Vec::new(); for (y, row) in grid.iter().enumerate() { for (x, cell) in row.iter().enumerate() { if cell != &Cell::PRoll { continue; } let neighbours = GRID_OFFSETS.iter().filter_map(|(xoff, yoff)| Some((x.checked_add_signed(*xoff)?, y.checked_add_signed(*yoff)?))).filter_map(|(x, y)| { let cell = grid.get(y)?.get(x)?; Some((x, y, cell.clone())) }).filter(|(_, _, c)| c == &Cell::PRoll).count(); if neighbours < 4 { result += 1; to_remove.push((x, y)); } } } if to_remove.is_empty() { break; } for (x, y) in to_remove { grid[y][x] = Cell::Empty; } } println!("Result: {}", result); }