<jupyter_start><jupyter_text>Stable Marriage ProblemThe stable marriage problem is defined as follows:Suppose you have N men and N women, and each person has ranked their prospective opposite-sex partners in order of preference.For example, if N = 3, the input could be something like this:```pythonguy_preferences = {    'andrew': ['caroline', 'abigail', 'betty'],    'bill': ['caroline', 'betty', 'abigail'],    'chester': ['betty', 'caroline', 'abigail'],}``````pythongal_preferences = {    'abigail': ['andrew', 'bill', 'chester'],    'betty': ['bill', 'andrew', 'chester'],    'caroline': ['bill', 'chester', 'andrew']}```Write an algorithm that pairs the men and women together in such a way that no two people of opposite sex would both rather be with each other than with their current partners.  SolutionDon't be upset if you found this problem challenging: the Gale-Shapley algorithm to solve this ended up earning one its creators a Nobel Prize!The algorithm is as follows:At each step, we consider one currently unmarried man. This man goes through his list of partners, proposing to each one. If the woman is unmarried, she agrees automatically. Otherwise, she will consider whether she prefers this new suitor to her current husband. If she does, she "trade up" to the new offer.With the input above:- Andrew proposes to Caroline. Since Caroline is currently available, she says yes, and they get paired up. - Next, Bill has Caroline as her first choice. Unfortunately for Andrew, Caroline prefers Bill, so she dumps Andrew and pairs up with Bill.- Andrew goes to her second choice Abigail, and she agrees.- Finally Chester asks Betty to marry. Sadly for Betty, even though Chester is her least favorite, she has no choice but to agree. ```   men   |  women  | pairs-----------------------------A, B, C  | A, B, C |    -B, C     | A, B    | (A, C)A, C     | A, B    | (B, C)C        | B       | (B, C), (A, A)    -    |    -    | (B, C), (A, A), (C, B)```  How do we know this algorithm works?Each man must get married, or exhaust his list. In this algorithm, once a woman is married, she can't be single again - but can only exchange partners. Since every gal getting married means every guy getting married, we have reached a contradiction. We must also show that this matching is good that no two people (guy **and** gal) should secretly desire each other more than their current partners. This is impossible. As each guy goes through his list there are two scenarios:- The gal **first** accepted his offer and **later** took another guy, in which case she won't desire him now.- The gal rejects him as she is already in a stable marriage, which again means she cannot desire him now. Therefore, this algorithm will provide stable pairing, BUT not everyone will be happy. :)<jupyter_code>def format_input(guys, gals):
    # reverse guys preferences, so popping the most desired gal takes O(1) time
    guys = {guy: list(reversed(prefs)) for guy, prefs in guys.items()}
    
    # gal preferences are stored in a dict, so that comparing guys is O(1)
    for gal, prefs in gals.items():
        gals.update({gal: {guy: i for i, guy in enumerate(prefs)}})
    
    return guys, gals
def match(guys, gals):
    pairs = {}
    
    guys_prefs, gals_prefs = format_input(guys, gals)
    
    married_men = set()
    married_women = set()
    
    bachelors = list(guys_prefs.keys())
    
    while bachelors:
        man1 = bachelors.pop()
        
        while man1 not in married_men:
            # find the gal he prefers O(1)
            woman = guys_prefs[man1].pop()
            
            # if desired woman is not married, pair with the current man
            if woman not in married_women:
                married_men.add(man1)
                married_women.add(woman)
                pairs[woman] = man1
            else:
                # she's already married, now check if she desires this new man
                # compare current husband with the new man(man1)
                her_current_man = pairs[woman]

                if gals_prefs[woman][man1] < gals_prefs[woman][her_current_man]:  # O(1)
                    married_men.remove(her_current_man)
                    bachelors.append(her_current_man)
                    married_men.add(man1)
                    pairs[woman] = man1
    return pairs
guys_preferences = {
    'andrew': ['caroline', 'abigail', 'betty'],
    'bill': ['caroline', 'betty', 'abigail'],
    'chester': ['betty', 'caroline', 'abigail'],
}

gals_preferences = {
    'abigail': ['andrew', 'bill', 'chester'],
    'betty': ['bill', 'andrew', 'chester'],
    'caroline': ['bill', 'chester', 'andrew']
}
match(guys_preferences, gals_preferences)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10519645120405577, 'fraction_numerical': 0.002957329953527672, 'mean_word_length': 3.01271186440678, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '406179', 'license': 'MIT', 'n_tokens_mistral': 1368, 'n_tokens_neox': 1312, 'n_words': 587, 'path': 'others/stable_marriage_problem.ipynb', 'repo_name': 'codacy-badger/algorithms-1', 'size': '4734'}