fn p1_walk(graph: &Graph, visited: &mut P1Visited, current: Cave, counter: &mut usize) {
    let neighbors = match current {
        Cave::Start => unreachable!(),
        Cave::End => {
            *counter += 1;
            return;
        }
        Cave::Small(current) | Cave::Big(current) => &graph.0[usize::from(current)],
    };

    neighbors
        .iter()
        .copied()
        .filter(|&cave| cave != Cave::Start)
        .for_each(|next| {
            if let Cave::Small(s) = next {
                if visited.push(s) {
                    return;
                }
            }
            p1_walk(graph, visited, next, counter);
            if let Cave::Small(s) = next {
                visited.pop(s);
            }
        })
}
// since we only care about if nodes have been visited or not, we can use a DFS and handle the
// visited map like a stack
since we only care about if nodes have been visited or not, we can use a DFS and handle the
visited map like a stack
since we only care about if nodes have been visited or not we can use a DFS and handle the visited map like a stack
fn p1_walk(graph: &Graph, visited: &mut P1Visited, current: Cave, counter: &mut usize) {
    let neighbors = match current {
        Cave::Start => unreachable!(),
        Cave::End => {
            *counter += 1;
            return;
        }
        Cave::Small(current) | Cave::Big(current) => &graph.0[usize::from(current)],
    };
    neighbors
        .iter()
        .copied()
        .filter(|&cave| cave != Cave::Start)
        .for_each(|next| {
            if let Cave::Small(s) = next {
                if visited.push(s) {
                    return;
                }
            }
            p1_walk(graph, visited, next, counter);
            if let Cave::Small(s) = next {
                visited.pop(s);
            }
        })
}
fn p1_walk ( graph : & Graph , visited : & mut P1Visited , current : Cave , counter : & mut usize ) { let neighbors = match current { Cave :: Start => unreachable ! ( ) , Cave :: End => { * counter += 1 ; return ; } Cave :: Small ( current ) | Cave :: Big ( current ) => & graph . 0 [ usize :: from ( current ) ] , } ; neighbors . iter ( ) . copied ( ) . filter ( | & cave | cave != Cave :: Start ) . for_each ( | next | { if let Cave :: Small ( s ) = next { if visited . push ( s ) { return ; } } p1_walk ( graph , visited , next , counter ) ; if let Cave :: Small ( s ) = next { visited . pop ( s ) ; } } ) }
since we only care about if nodes have been visited or not, we can use a DFS and handle the
visited map like a stack
since we only care about if nodes have been visited or not we can use a DFS and handle the visited map like a stack
graph
&Graph
visited
&mut P1Visited
current
Cave
counter
&mut usize
graph
&Graph
visited
&mut P1Visited
current
Cave
counter
&mut usize