use aoc_runner_derive::{aoc, aoc_generator}; type Field = Vec>; #[aoc_generator(day18)] fn parse(input: &str) -> Field { let w = input.lines().next().unwrap().len(); let h = input.lines().count(); let mut result = vec![vec![false; h + 2]; w + 2]; input.lines().enumerate().for_each(|(y, line)| { line.chars() .enumerate() .for_each(|(x, c)| result[x + 1][y + 1] = c == '#'); }); result } #[aoc(day18, part1)] fn part1(input: &Field) -> usize { let mut current = input.clone(); let mut next = input.clone(); for _ in 0..100 { for x in 1..current.len() - 1 { for y in 1..current.len() - 1 { let now = current[x][y]; let neighbors_on: usize = count_neighbors(¤t, x, y); let new = if now { neighbors_on == 2 || neighbors_on == 3 } else { neighbors_on == 3 }; next[x][y] = new; } } (current, next) = (next, current); } current.into_iter().flatten().filter(|x| *x).count() } #[aoc(day18, part2)] fn part2(input: &Field) -> usize { let mut current = input.clone(); let mut next = input.clone(); let l = current.len() - 2; for _ in 0..100 { for x in 1..current.len() - 1 { for y in 1..current.len() - 1 { if x == 1 && y == 1 || x == 1 && y == l || x == l && y == 1 || x == l && y == l { next[x][y] = true; continue; } let now = current[x][y]; let neighbors_on: usize = count_neighbors(¤t, x, y); let new = if now { neighbors_on == 2 || neighbors_on == 3 } else { neighbors_on == 3 }; next[x][y] = new; } } (current, next) = (next, current); } current.into_iter().flatten().filter(|x| *x).count() } fn count_neighbors(field: &Field, x: usize, y: usize) -> usize { let mut result = 0; if field[x - 1][y - 1] { result += 1; } if field[x][y - 1] { result += 1; } if field[x + 1][y - 1] { result += 1; } if field[x - 1][y] { result += 1; } if field[x + 1][y] { result += 1; } if field[x - 1][y + 1] { result += 1; } if field[x][y + 1] { result += 1; } if field[x + 1][y + 1] { result += 1; } result }