use pathfinding::prelude::{dijkstra, dijkstra_bidirectional};
use std::time::Instant;
const SIZE: i32 = 400;
const START: (i32, i32) = (SIZE / 2, SIZE / 2);
const GOAL: (i32, i32) = (SIZE, SIZE);
#[expect(clippy::trivially_copy_pass_by_ref)]
fn neighbours(&(x, y): &(i32, i32)) -> Vec<((i32, i32), usize)> {
[(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
.into_iter()
.filter(|&(nx, ny)| (0..=SIZE).contains(&nx) && (0..=SIZE).contains(&ny))
.map(|(nx, ny)| ((nx, ny), 1 + (x + y + nx + ny).unsigned_abs() as usize % 3))
.collect()
}
fn main() {
let instant = Instant::now();
let (_, cost) = dijkstra(&START, neighbours, |p| *p == GOAL).expect("no path found");
let duration_dijkstra = instant.elapsed();
let instant = Instant::now();
let (_, cost_bidirectional) =
dijkstra_bidirectional(&START, &GOAL, neighbours, neighbours).expect("no path found");
let duration_bidirectional = instant.elapsed();
assert_eq!(cost, cost_bidirectional);
println!("Shortest path cost: {cost}");
println!("Dijkstra took {duration_dijkstra:?}");
println!("Bidirectional Dijkstra took {duration_bidirectional:?}");
}