11use crate :: utils:: graphs:: graph:: Graph ;
2- use std:: collections:: { HashMap , VecDeque } ;
2+ use std:: collections:: { HashMap , HashSet , VecDeque } ;
33use std:: hash:: Hash ;
44
55pub trait IsEnd < T > {
@@ -24,7 +24,7 @@ pub struct AllPaths<'a, T: 'a> {
2424
2525impl < ' a , T > From < & ' a Graph < T > > for AllPaths < ' a , T >
2626where
27- T : Eq + Hash + Copy + PartialEq + Clone ,
27+ T : Eq + Hash + Copy + PartialEq ,
2828{
2929 fn from ( graph : & ' a Graph < T > ) -> Self {
3030 Self :: new ( move |p : T | graph. neighbours ( & p) )
@@ -33,15 +33,15 @@ where
3333
3434impl < ' a , T > From < & ' a HashMap < T , Vec < T > > > for AllPaths < ' a , T >
3535where
36- T : Eq + Hash + Copy + PartialEq + Clone ,
36+ T : Eq + Hash + Copy + PartialEq ,
3737{
3838 fn from ( value : & ' a HashMap < T , Vec < T > > ) -> Self {
3939 Self :: new ( move |p : T | value. get ( & p) . unwrap ( ) . to_vec ( ) )
4040 }
4141}
4242impl < ' a , T > AllPaths < ' a , T >
4343where
44- T : PartialEq + Clone ,
44+ T : Eq + Hash + Copy ,
4545{
4646 pub fn new ( adjacency : impl Fn ( T ) -> Vec < T > + ' a ) -> Self {
4747 Self {
5454 E : IsEnd < T > ,
5555 {
5656 let mut paths: Vec < VecDeque < T > > = Vec :: new ( ) ;
57+ let mut visited = HashSet :: new ( ) ;
58+ let mut path = VecDeque :: new ( ) ;
5759
58- self . visit ( start, & end, Vec :: new ( ) , VecDeque :: new ( ) , & mut paths) ;
60+ self . visit ( start, & end, & mut visited , & mut path , & mut paths) ;
5961
6062 paths
6163 }
@@ -64,26 +66,27 @@ where
6466 & self ,
6567 from : T ,
6668 end : & E ,
67- mut visited : Vec < T > ,
68- mut path : VecDeque < T > ,
69+ visited : & mut HashSet < T > ,
70+ path : & mut VecDeque < T > ,
6971 paths : & mut Vec < VecDeque < T > > ,
7072 ) where
7173 E : IsEnd < T > ,
7274 {
73- visited. push ( from. clone ( ) ) ;
74- path. push_back ( from. clone ( ) ) ;
75+ visited. insert ( from) ;
76+ path. push_back ( from) ;
7577
7678 if end. is_end ( & from) {
7779 paths. push ( path. clone ( ) ) ;
78-
79- return ;
80- }
81-
82- for p in ( self . adjacency ) ( from) {
83- if !visited. contains ( & p) {
84- self . visit ( p, end, visited. clone ( ) , path. clone ( ) , paths) ;
80+ } else {
81+ for p in ( self . adjacency ) ( from) {
82+ if !visited. contains ( & p) {
83+ self . visit ( p, end, visited, path, paths) ;
84+ }
8585 }
8686 }
87+
88+ path. pop_back ( ) ;
89+ visited. remove ( & from) ;
8790 }
8891}
8992
@@ -95,7 +98,7 @@ mod tests {
9598 use std:: collections:: { HashMap , VecDeque } ;
9699
97100 #[ test]
98- fn generate ( ) {
101+ fn paths ( ) {
99102 let p0 = Point :: new ( 0 , 0 ) ;
100103 let p1 = Point :: new ( 1 , 1 ) ;
101104 let p2 = Point :: new ( 2 , 2 ) ;
@@ -107,9 +110,8 @@ mod tests {
107110 ( p2, vec ! [ p0, p1] ) ,
108111 ( p3, vec ! [ ] ) ,
109112 ] ) ;
110- let adjacency = |p : Point | graph. get ( & p) . unwrap ( ) . to_vec ( ) ;
111113
112- let all_paths: AllPaths < Point > = AllPaths :: new ( adjacency ) ;
114+ let all_paths = AllPaths :: from ( & graph ) ;
113115
114116 let paths = all_paths. paths ( p2, p3) ;
115117
0 commit comments