#[derive(Clone, Copy, Debug)]
enum Tile {
Unvisited,
Visited,
Impassable,
}
type World = Vec<Vec<Tile>>;
#[decurse::decurse]
fn dfs_paint(mut world: World, (x, y): (isize, isize)) -> World {
let here = &mut world[x as usize][y as usize];
*here = Tile::Visited;
const CHANGE: [isize; 3] = [1, 0, -1];
for di in &CHANGE {
let i = x + *di;
if (i >= world.len() as isize) || (i < 0) {
continue;
}
for dj in &CHANGE {
let j = y + *dj;
if (j >= world[i as usize].len() as isize) || (j < 0) {
continue;
}
let neighbor = &mut world[i as usize][j as usize];
match neighbor {
Tile::Unvisited => world = dfs_paint(world, (i, j)),
_ => {}
}
}
}
world
}
fn main() {
const SIZE: usize = 1000;
const HALF: usize = SIZE / 2;
let mut world = vec![vec![Tile::Unvisited; SIZE]; SIZE];
world[HALF].fill(Tile::Impassable);
world = dfs_paint(world, (0, 0));
let first_half_visited = world[..HALF]
.iter()
.map(|row| {
row.iter().all(|v| match v {
Tile::Visited => true,
_ => false,
})
})
.all(|v| v);
assert_eq!(first_half_visited, true);
let last_half_unvisited = world[(HALF + 1)..]
.iter()
.map(|row| {
row.iter().all(|v| match v {
Tile::Unvisited => true,
_ => false,
})
})
.all(|v| v);
assert_eq!(last_half_unvisited, true);
}