fn distances(origin: Vec2D, walls: &Walls, keys: &Map, doors: &Map) -> Vec<KeyDistance> {
    let mut visited = HashSet::new();
    let mut queue = VecDeque::new();
    let mut edges = Vec::new();

    queue.push_back((origin, 0, 0, 0));
    while let Some((pos, steps, have_keys, seen_doors)) = queue.pop_front() {
        visited.insert(pos);
        let candidates = [UP, DOWN, LEFT, RIGHT]
            .iter()
            .map(|&dir| pos + dir)
            .filter(|new_pos| !visited.contains(new_pos) && !walls.contains(new_pos));
        for new_pos in candidates {
            let new_key = *keys.get(&new_pos).unwrap_or(&0);
            let new_steps = steps + 1;
            if new_key != 0 {
                edges.push(KeyDistance {
                    to: new_key,
                    steps: new_steps,
                    keys: have_keys,
                    doors: seen_doors,
                });
            }
            queue.push_back((
                new_pos,
                new_steps,
                have_keys | new_key,
                seen_doors | *doors.get(&new_pos).unwrap_or(&0),
            ))
        }
    }
    edges
}
// Returns the distance from 'key' to all other keys and what doors are along
// the route.
Returns the distance from 'key' to all other keys and what doors are along
the route.
Returns the distance from ' key ' to all other keys and what doors are along the route .
fn distances(origin: Vec2D, walls: &Walls, keys: &Map, doors: &Map) -> Vec<KeyDistance> {
    let mut visited = HashSet::new();
    let mut queue = VecDeque::new();
    let mut edges = Vec::new();
    queue.push_back((origin, 0, 0, 0));
    while let Some((pos, steps, have_keys, seen_doors)) = queue.pop_front() {
        visited.insert(pos);
        let candidates = [UP, DOWN, LEFT, RIGHT]
            .iter()
            .map(|&dir| pos + dir)
            .filter(|new_pos| !visited.contains(new_pos) && !walls.contains(new_pos));
        for new_pos in candidates {
            let new_key = *keys.get(&new_pos).unwrap_or(&0);
            let new_steps = steps + 1;
            if new_key != 0 {
                edges.push(KeyDistance {
                    to: new_key,
                    steps: new_steps,
                    keys: have_keys,
                    doors: seen_doors,
                });
            }
            queue.push_back((
                new_pos,
                new_steps,
                have_keys | new_key,
                seen_doors | *doors.get(&new_pos).unwrap_or(&0),
            ))
        }
    }
    edges
}
fn distances ( origin : Vec2D , walls : & Walls , keys : & Map , doors : & Map ) -> Vec < KeyDistance > { let mut visited = HashSet :: new ( ) ; let mut queue = VecDeque :: new ( ) ; let mut edges = Vec :: new ( ) ; queue . push_back ( ( origin , 0 , 0 , 0 ) ) ; while let Some ( ( pos , steps , have_keys , seen_doors ) ) = queue . pop_front ( ) { visited . insert ( pos ) ; let candidates = [ UP , DOWN , LEFT , RIGHT ] . iter ( ) . map ( | & dir | pos + dir ) . filter ( | new_pos | ! visited . contains ( new_pos ) && ! walls . contains ( new_pos ) ) ; for new_pos in candidates { let new_key = * keys . get ( & new_pos ) . unwrap_or ( & 0 ) ; let new_steps = steps + 1 ; if new_key != 0 { edges . push ( KeyDistance { to : new_key , steps : new_steps , keys : have_keys , doors : seen_doors , } ) ; } queue . push_back ( ( new_pos , new_steps , have_keys | new_key , seen_doors | * doors . get ( & new_pos ) . unwrap_or ( & 0 ) , ) ) } } edges }
Returns the distance from 'key' to all other keys and what doors are along
the route.
Returns the distance from ' key ' to all other keys and what doors are along the route .
origin
Vec2D
walls
&Walls
keys
&Map
doors
&Map
origin
Vec2D
walls
&Walls
keys
&Map
doors
&Map