1use crate::util::grid::*;
3use crate::util::point::*;
4
5type Input = (Vec<Point>, Grid<u8>);
6
7pub fn parse(input: &str) -> Input {
8 let grid = Grid::parse(input);
9 let offset = Point::new(1, 1);
10 let mut todo = Vec::new();
11 let mut padded = Grid::new(grid.width + 2, grid.height + 2, u8::MAX);
12
13 for y in 0..grid.height {
14 for x in 0..grid.width {
15 let point = Point::new(x, y);
16
17 if grid[point] == b'@' {
18 let count = DIAGONAL
19 .iter()
20 .map(|&d| point + d)
21 .filter(|&next| grid.contains(next) && grid[next] == b'@')
22 .count();
23
24 if count < 4 {
25 todo.push(point + offset);
26 }
27 padded[point + offset] = count as u8;
28 }
29 }
30 }
31
32 (todo, padded)
33}
34
35pub fn part1(input: &Input) -> usize {
36 let (todo, _) = input;
37 todo.len()
38}
39
40pub fn part2(input: &Input) -> usize {
41 let (mut todo, mut padded) = input.clone();
42 let mut removed = 0;
43
44 while let Some(point) = todo.pop() {
45 removed += 1;
46
47 for next in DIAGONAL.map(|d| point + d) {
48 if padded[next] == 4 {
49 todo.push(next);
50 }
51 padded[next] -= 1;
52 }
53 }
54
55 removed
56}