use crate::spatial::*; pub fn day4_part1(input: &str) -> String { let roll_locations = parse(input); removable_rolls(&roll_locations).count().to_string() } //fixed point algorithm go brrr pub fn day4_part2(input: &str) -> String { let mut prev_roll_locations = vec![vec![]]; let mut next_roll_locations = parse(input); let mut rolls_removed = 0; while prev_roll_locations != next_roll_locations { prev_roll_locations = next_roll_locations.clone(); for roll_coords in removable_rolls(&prev_roll_locations) { next_roll_locations[roll_coords.row][roll_coords.col] = false; rolls_removed += 1; } } rolls_removed.to_string() } fn removable_rolls(roll_locations: &[Vec]) -> impl Iterator { all_coords(roll_locations[0].len(), roll_locations.len()) .filter(|coords| roll_locations[coords.row][coords.col]) .filter(|&coords| { adjacent_including_diagonals(roll_locations, coords) .iter() .flatten() .filter(|&&neighbour| neighbour) .count() < 4 }) } fn parse(input: &str) -> Vec> { input .lines() .map(|line| line.chars().map(|c| c == '@').collect()) .collect() }