@@ -4,6 +4,33 @@ pub fn stable_matching(
44 men_preferences : & HashMap < String , Vec < String > > ,
55 women_preferences : & HashMap < String , Vec < String > > ,
66) -> HashMap < String , String > {
7+ let ( mut free_men, mut current_partner, mut man_engaged, mut next_proposal) =
8+ initialize_data_structures ( men_preferences, women_preferences) ;
9+
10+ while let Some ( man) = free_men. pop_front ( ) {
11+ handle_proposal (
12+ & man,
13+ & mut free_men,
14+ & mut current_partner,
15+ & mut man_engaged,
16+ & mut next_proposal,
17+ men_preferences,
18+ women_preferences,
19+ ) ;
20+ }
21+
22+ extract_stable_matches ( man_engaged)
23+ }
24+
25+ fn initialize_data_structures (
26+ men_preferences : & HashMap < String , Vec < String > > ,
27+ women_preferences : & HashMap < String , Vec < String > > ,
28+ ) -> (
29+ VecDeque < String > ,
30+ HashMap < String , Option < String > > ,
31+ HashMap < String , Option < String > > ,
32+ HashMap < String , usize > ,
33+ ) {
734 let mut free_men: VecDeque < String > = VecDeque :: new ( ) ;
835 let mut current_partner: HashMap < String , Option < String > > = HashMap :: new ( ) ;
936 let mut man_engaged: HashMap < String , Option < String > > = HashMap :: new ( ) ;
@@ -18,48 +45,76 @@ pub fn stable_matching(
1845 current_partner. insert ( woman. clone ( ) , None ) ;
1946 }
2047
21- fn woman_prefers_new_man (
22- woman : & str ,
23- man1 : & str ,
24- man2 : & str ,
25- preferences : & HashMap < String , Vec < String > > ,
26- ) -> bool {
27- let woman_preferences = & preferences[ woman] ;
28- woman_preferences. iter ( ) . position ( |m| m == man1) . unwrap ( )
29- < woman_preferences. iter ( ) . position ( |m| m == man2) . unwrap ( )
30- }
48+ ( free_men, current_partner, man_engaged, next_proposal)
49+ }
3150
32- while let Some ( man) = free_men. pop_front ( ) {
33- let man_pref_list = & men_preferences[ & man] ;
34- let next_woman_idx = * next_proposal. get ( & man) . unwrap ( ) ;
35- let woman = & man_pref_list[ next_woman_idx] ;
36-
37- next_proposal. insert ( man. clone ( ) , next_woman_idx + 1 ) ;
38-
39- if let Some ( current_man) = current_partner[ woman] . clone ( ) {
40- if woman_prefers_new_man ( woman, & man, & current_man, women_preferences) {
41- man_engaged. insert ( man. clone ( ) , Some ( woman. clone ( ) ) ) ;
42- current_partner. insert ( woman. clone ( ) , Some ( man. clone ( ) ) ) ;
43- free_men. push_back ( current_man) ;
44- } else {
45- free_men. push_back ( man) ;
46- }
51+ fn handle_proposal (
52+ man : & str ,
53+ free_men : & mut VecDeque < String > ,
54+ current_partner : & mut HashMap < String , Option < String > > ,
55+ man_engaged : & mut HashMap < String , Option < String > > ,
56+ next_proposal : & mut HashMap < String , usize > ,
57+ men_preferences : & HashMap < String , Vec < String > > ,
58+ women_preferences : & HashMap < String , Vec < String > > ,
59+ ) {
60+ let man_pref_list = & men_preferences[ man] ;
61+ let next_woman_idx = * next_proposal. get ( man) . unwrap ( ) ;
62+ let woman = & man_pref_list[ next_woman_idx] ;
63+
64+ next_proposal. insert ( man. to_string ( ) , next_woman_idx + 1 ) ;
65+
66+ if let Some ( current_man) = current_partner[ woman] . clone ( ) {
67+ if woman_prefers_new_man ( woman, man, & current_man, women_preferences) {
68+ update_engagement (
69+ man,
70+ woman,
71+ current_man,
72+ free_men,
73+ current_partner,
74+ man_engaged,
75+ ) ;
4776 } else {
48- man_engaged. insert ( man. clone ( ) , Some ( woman. clone ( ) ) ) ;
49- current_partner. insert ( woman. clone ( ) , Some ( man. clone ( ) ) ) ;
77+ free_men. push_back ( man. to_string ( ) ) ;
5078 }
79+ } else {
80+ man_engaged. insert ( man. to_string ( ) , Some ( woman. to_string ( ) ) ) ;
81+ current_partner. insert ( woman. to_string ( ) , Some ( man. to_string ( ) ) ) ;
5182 }
83+ }
84+
85+ fn update_engagement (
86+ man : & str ,
87+ woman : & str ,
88+ current_man : String ,
89+ free_men : & mut VecDeque < String > ,
90+ current_partner : & mut HashMap < String , Option < String > > ,
91+ man_engaged : & mut HashMap < String , Option < String > > ,
92+ ) {
93+ man_engaged. insert ( man. to_string ( ) , Some ( woman. to_string ( ) ) ) ;
94+ current_partner. insert ( woman. to_string ( ) , Some ( man. to_string ( ) ) ) ;
95+ free_men. push_back ( current_man) ;
96+ }
97+
98+ fn woman_prefers_new_man (
99+ woman : & str ,
100+ man1 : & str ,
101+ man2 : & str ,
102+ preferences : & HashMap < String , Vec < String > > ,
103+ ) -> bool {
104+ let woman_preferences = & preferences[ woman] ;
105+ woman_preferences. iter ( ) . position ( |m| m == man1) . unwrap ( )
106+ < woman_preferences. iter ( ) . position ( |m| m == man2) . unwrap ( )
107+ }
52108
53- let mut stable_matches: HashMap < String , String > = HashMap :: new ( ) ;
109+ fn extract_stable_matches ( man_engaged : HashMap < String , Option < String > > ) -> HashMap < String , String > {
110+ let mut stable_matches = HashMap :: new ( ) ;
54111 for ( man, woman_option) in man_engaged {
55112 if let Some ( woman) = woman_option {
56113 stable_matches. insert ( man, woman) ;
57114 }
58115 }
59-
60116 stable_matches
61117}
62-
63118#[ cfg( test) ]
64119mod tests {
65120 use super :: * ;
0 commit comments