def creer_dico_resultats(votes):
    D = {}
    for bulletin in votes:
        if bulletin in D:
            D[bulletin] += 1
        else:
            D[bulletin] = 1
    return D

def cle_de_valeur_max(D):
    max = 0
    for cle in D:
        valeur = D[cle]
        if valeur > max:
            max = valeur
            cle_max = cle
    return cle_max


def scrutin_un_tour(votes):
    D = creer_dico_resultats(votes)
    return cle_de_valeur_max(D)



preferences = [['Alice', 'Charlie', 'Dave', 'Bob'], ['Bob', 'Charlie', 'Dave', 'Alice'], ['Alice', 'Dave', 'Charlie', 'Bob'], ['Dave', 'Charlie', 'Bob', 'Alice'], ['Alice', 'Bob', 'Charlie', 'Dave'], ['Charlie', 'Dave', 'Bob', 'Alice'], ['Bob', 'Dave', 'Charlie', 'Alice']]


def candidats_second_tour(D):
    p = cle_de_valeur_max(D)
    max = 0
    for cle in D:
        if cle != p and D[cle] > max:
            max = valeur
            s = cle
    return p,s

def vote_second_tour(bulletin,p,s):
    for c in bulletin:
        if c==p or c==s:
            return c

def scrutin_deux_tours(votes):
    votes_premier_tour = [bulletin[0] for bulletin in votes]
    resultats_premier_tour = creer_dico_resultats(votes_premier_tour)
    p,s = candidats_second_tour(resultats_premier_tour)
    votes_second_tour = [vote_second_tour(bulletin,p,s) for bulletin in votes]
    return scrutin_un_tour(votes_second_tour)


from random import *

def dictature_aleatoire(T):
    n = len(T)
    k = randint(0,n-1)
    return T[k]

def liste_sans(L,a):
    R=[]
    for x in l:
        if x!=a:
            R.append(x)
    return R

def enlever_candidat(T,p):
    R=[]
    for L in T:
        L2 = liste_sans(L,p)
        R.append(L2)
    return R

def cle_de_valeur_min(D):
    min = float('inf')
    for cle in D:
        if D[cle] < min or (D[cle] == min and cle < cle_min) :
            min = D[cle]
            cle_min = cle
    return cle_min



def dernier(votes):
    votes_tour_courant = [bulletin[0] for bulletin in votes]
    resultats = creer_dico_resultats(votes_tour_courant)
    for bulletin in votes:
        for c in bulletin:
            if c not in resultats:
                resultats[c] = 0
    return cle_de_valeur_min(resultats)

def scrutin_elimination(votes):
    R=votes
    while len(R[0]) > 1:
        p = dernier(R)
        R = enlever_candidat(R,p)
    return R[0][0]



def duel(votes,c1,c2):
    votes_duel = [vote_second_tour(bulletin,c1,c2) for bulletin in votes]
    return scrutin_un_tour(votes_duel)

def liste_candidats(votes):
    L = []
    for bulletin in votes:
        for candidat in bulletin:
            if candidat not in L:
                L.append(candidat)
    return L

def est_vainqueur_condorcet(votes,L,c):
    for x in L:
        if x!=c and duel(votes,x,c)==x:
            return False
    return True


def scrutin_condorcet(votes):
    L = liste_candidats(votes)
    for c in L:
        if est_vainqueur_condorcet(votes,L,c):
            return c
    return None




