use std::collections::VecDeque;
use crate::IndexedClimber;
pub struct Bfs<C: IndexedClimber> {
climber: C,
queue: VecDeque<C::Index>,
}
pub struct BfsWithDepth<C: IndexedClimber> {
climber: C,
queue: VecDeque<(C::Index, usize)>,
}
impl<C: IndexedClimber> Bfs<C> {
pub fn new(climber: C) -> Self {
let index = climber.index();
Self {
climber,
queue: VecDeque::from([index]),
}
}
pub fn with_depth(self) -> BfsWithDepth<C> {
BfsWithDepth {
climber: self.climber,
queue: self.queue.into_iter().map(|index| (index, 0)).collect(),
}
}
}
impl<C: IndexedClimber> Iterator for Bfs<C> {
type Item = C::Item;
fn next(&mut self) -> Option<Self::Item> {
let index = self.queue.pop_front()?;
let item = self.climber.go_to(&index)?;
self.queue.extend(self.climber.child_indices());
Some(item)
}
}
impl<C: IndexedClimber> Iterator for BfsWithDepth<C> {
type Item = (usize, C::Item);
fn next(&mut self) -> Option<Self::Item> {
let (index, depth) = self.queue.pop_front()?;
let item = self.climber.go_to(&index)?;
self.queue
.extend(self.climber.child_indices().map(|index| (index, depth + 1)));
Some((depth, item))
}
}