1
+ use std:: collections:: { HashMap , HashSet } ;
2
+
3
+ pub fn run ( ) {
4
+ for i in [
5
+ // (vec!["bread"], vec![vec!["yeast","flour"]], vec!["yeast","flour","corn"]),
6
+ // (vec!["bread","sandwich"], vec![vec!["yeast","flour"],vec!["bread","meat"]], vec!["yeast","flour","meat"]),
7
+ // (vec!["bread","sandwich","burger"], vec![vec!["yeast","flour"],vec!["bread","meat"],vec!["sandwich","meat","bread"]], vec!["yeast","flour","meat"]),
8
+ ( vec ! [ "ju" , "fzjnm" , "x" , "e" , "zpmcz" , "h" , "q" ] , vec ! [ vec![ "d" ] , vec![ "hveml" , "f" , "cpivl" ] , vec![ "cpivl" , "zpmcz" , "h" , "e" , "fzjnm" , "ju" ] , vec![ "cpivl" , "hveml" , "zpmcz" , "ju" , "h" ] , vec![ "h" , "fzjnm" , "e" , "q" , "x" ] , vec![ "d" , "hveml" , "cpivl" , "q" , "zpmcz" , "ju" , "e" , "x" ] , vec![ "f" , "hveml" , "cpivl" ] ] , vec ! [ "f" , "hveml" , "cpivl" , "d" ] ) ,
9
+ ( vec ! [ "g" , "dfk" , "diyob" , "kkx" , "or" , "qniq" , "qhy" , "b" , "jk" , "rcy" ] , vec ! [ vec![ "eescu" , "in" , "hbgw" , "ardh" , "ii" , "om" ] , vec![ "ii" , "ardh" , "in" , "hbgw" ] , vec![ "ardh" , "rcy" ] , vec![ "ardh" , "ii" , "eescu" , "hbgw" , "rcy" , "jk" , "b" ] , vec![ "hbgw" , "ii" , "in" , "ardh" , "om" ] , vec![ "gjotw" ] , vec![ "in" , "ardh" , "hbgw" , "om" , "ii" , "kkx" , "qniq" ] , vec![ "om" , "hbgw" , "ii" , "ardh" , "in" , "eescu" ] , vec![ "ii" , "om" , "hbgw" , "eescu" ] , vec![ "om" , "hbgw" , "in" , "ardh" , "eescu" ] ] , vec ! [ "om" , "hbgw" , "in" , "ardh" , "eescu" , "ii" ] )
10
+ ] {
11
+ println ! ( "{:?}" , find_all_recipes( i. 0 . iter( ) . map( |x| x. to_string( ) ) . collect:: <Vec <String >>( ) , i. 1 . iter( ) . map( |x| x. iter( ) . map( |y| y. to_string( ) ) . collect:: <Vec <String >>( ) ) . collect:: <Vec <Vec <String >>>( ) , i. 2 . iter( ) . map( |x| x. to_string( ) ) . collect:: <Vec <String >>( ) ) ) ;
12
+ }
13
+ }
14
+
15
+ pub fn find_all_recipes ( recipes : Vec < String > , ingredients : Vec < Vec < String > > , supplies : Vec < String > ) -> Vec < String > {
16
+ let mut map = HashMap :: new ( ) ;
17
+ let mut supply_map: HashSet < String > = HashSet :: from_iter ( supplies) ;
18
+
19
+ for ( index, i) in recipes. iter ( ) . enumerate ( ) {
20
+ map. insert ( i. clone ( ) , ingredients[ index] . clone ( ) ) ;
21
+ }
22
+
23
+ pub fn resolve ( r : String , i : & HashMap < String , Vec < String > > , supplies : & mut HashSet < String > , traversed : & mut HashSet < String > ) -> bool {
24
+ match i. get ( & r) {
25
+ Some ( ingredients) => {
26
+ for ingredient in ingredients {
27
+ if !supplies. contains ( ingredient) {
28
+ if traversed. contains ( ingredient) {
29
+ return false ;
30
+ }
31
+ traversed. insert ( ingredient. clone ( ) ) ;
32
+
33
+ if !resolve ( ingredient. clone ( ) , & i, supplies, traversed) {
34
+ return false ;
35
+ }
36
+ }
37
+ }
38
+ supplies. insert ( r) ;
39
+ true
40
+ } ,
41
+ None => {
42
+ false
43
+ }
44
+ }
45
+ }
46
+
47
+ let mut result = vec ! [ ] ;
48
+
49
+ for ( k, _) in & map {
50
+ if resolve ( k. clone ( ) , & map, & mut supply_map, & mut HashSet :: new ( ) ) {
51
+ result. push ( k. clone ( ) ) ;
52
+ }
53
+ }
54
+
55
+ result
56
+ }
0 commit comments