110 lines
2.7 KiB
Rust
110 lines
2.7 KiB
Rust
use itertools::Itertools;
|
|
|
|
fn neighbors(grid: &Vec<Vec<char>>, position: (isize, isize)) -> i32 {
|
|
let width = grid[0].len() as isize;
|
|
let height = grid.len() as isize;
|
|
let mut num_tp = 0;
|
|
for y_offset in -1..=1 {
|
|
for x_offset in -1..=1 {
|
|
let search_position = (position.0 + x_offset, position.1 + y_offset);
|
|
if search_position == position
|
|
|| search_position.0 < 0
|
|
|| search_position.0 >= width
|
|
|| search_position.1 < 0
|
|
|| search_position.1 >= height
|
|
{
|
|
continue;
|
|
}
|
|
let cell = grid[search_position.1 as usize][search_position.0 as usize];
|
|
if cell == '@' {
|
|
num_tp += 1;
|
|
}
|
|
}
|
|
}
|
|
num_tp
|
|
}
|
|
|
|
pub fn process_part1(input: &str) -> i32 {
|
|
let grid = input
|
|
.lines()
|
|
.map(|line| line.chars().collect_vec())
|
|
.collect_vec();
|
|
let width = grid[0].len() as isize;
|
|
let height = grid.len() as isize;
|
|
let mut accessible_tp = 0;
|
|
for y in 0..height {
|
|
for x in 0..width {
|
|
if grid[y as usize][x as usize] != '@' {
|
|
continue;
|
|
}
|
|
let neighbors = neighbors(&grid, (x, y));
|
|
if neighbors < 4 {
|
|
accessible_tp += 1;
|
|
}
|
|
}
|
|
}
|
|
accessible_tp
|
|
}
|
|
|
|
pub fn process_part2(input: &str) -> i32 {
|
|
let mut grid = input
|
|
.lines()
|
|
.map(|line| line.chars().collect_vec())
|
|
.collect_vec();
|
|
let width = grid[0].len() as isize;
|
|
let height = grid.len() as isize;
|
|
let mut accessible_tp_total = 0;
|
|
loop {
|
|
let mut accessible_tp = 0;
|
|
let mut new_grid = grid.clone();
|
|
for y in 0..height {
|
|
for x in 0..width {
|
|
if grid[y as usize][x as usize] != '@' {
|
|
continue;
|
|
}
|
|
let neighbors = neighbors(&grid, (x, y));
|
|
if neighbors < 4 {
|
|
accessible_tp += 1;
|
|
new_grid[y as usize][x as usize] = '.';
|
|
} else {
|
|
new_grid[y as usize][x as usize] = '@';
|
|
}
|
|
}
|
|
}
|
|
if accessible_tp == 0 {
|
|
break;
|
|
}
|
|
grid = new_grid;
|
|
accessible_tp_total += accessible_tp;
|
|
}
|
|
accessible_tp_total
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
const INPUT: &str = "..@@.@@@@.
|
|
@@@.@.@.@@
|
|
@@@@@.@.@@
|
|
@.@@@@..@.
|
|
@@.@@@@.@@
|
|
.@@@@@@@.@
|
|
.@.@.@.@@@
|
|
@.@@@.@@@@
|
|
.@@@@@@@@.
|
|
@.@.@@@.@.";
|
|
|
|
#[test]
|
|
fn part1() {
|
|
let result = process_part1(INPUT);
|
|
assert_eq!(result, 13);
|
|
}
|
|
|
|
#[test]
|
|
fn part2() {
|
|
let result = process_part2(INPUT);
|
|
assert_eq!(result, 43);
|
|
}
|
|
}
|