# TP 18 (fichier à compléter) : Dictionnaires
# BCPST1B 2025-2026
# Lycée Hoche, Versailles
# L.-C. LEFÈVRE

#%% partie II
# quelques tests
d = {"sexe": "2", "prenom": "EMMA", "annee": "2004", "nombre": "6634"}

#%% itérer sur les clés
for k in d.keys():
    print(k)

#%% itérer sur les valeurs
for v in d.values():
    print(v)

#%% itérer sur les couples
for (k, v) in d.items():
    print("clé :", k, "valeur :", v)

#%% exercice 1.1

def facture(d):
    S = 0
    for v in d.values():
        S = S + v
    return S

# test
courses = {"pain": 1.20, "camembert": 3.0, "salade": 1.5, "savon": 3.5}
print(facture(courses))

#%% exercice 1.2

def est_trop_luxueux(d):
    for v in d.values():
        if v >= 5:
            return True
    return False

# test
courses_1 = {"pain": 1.20, "camembert": 3.0, "salade": 1.5, "savon": 3.5}
print(est_trop_luxueux(courses_1))
courses_2 = {"pain": 1.20, "camembert": 3.0, "salade": 1.5, "savon": 3.5, "risotto aux truffes": 8}
print(est_trop_luxueux(courses_2))

#%% exercice 2.1

def nombre_ingrédients(d):
    N = 0
    for k in d.keys():
        N = N + 1
    return N

# test
crepes = {"farine": 250, "oeufs": 4, "lait": 300, "beurre": 50, "sucre": 30}
print(nombre_ingrédients(crepes))

#%% exercice 2.2

def est_sans_noix(d):
    for k in d.keys():
        if k == "noix":
            if d[k] > 0:
                return False
    return True

# test
crepes = {"farine": 250, "oeufs": 4, "lait": 300, "beurre": 50, "sucre": 30}
print(est_sans_noix(crepes))
tarte_aux_noix = {"noix": 200, "farine": 250, "oeufs": 4, "sucre": 100}
print(est_sans_noix(tarte_aux_noix))
brownie = {"farine": 300, "oeufs": 4, "sucre": 200, "chocolat": 180, "noix": 80}
print(est_sans_noix(brownie))
pain = {"farine": 250, "sel": 10, "eau": 130, "noix": 0, "levure": 5}
print(est_sans_noix(pain))

#%% exercice 2.3

def est_sain(d):
    for k in d.keys():
        if k == "sucre":
            if d[k] > 50:
                return False
    return True

# test
crepes = {"farine": 250, "oeufs": 4, "lait": 300, "beurre": 50, "sucre": 30}
print(est_sain(crepes))
tarte_citron = {"pate": 300, "citron": 500, "sucre": 200, "oeuf": 4}
print(est_sain(tarte_citron))
kebab = {"pain": 200, "viande": 150, "frites": 250, "salade": 30}
print(est_sain(kebab))

#%% exercice 3

def oseille(d):
    S = 0
    for (k, v) in d.items():
        S = S + k * v
    return S

# test
d = {1: 4, 2: 7, 10: 1}
print(oseille(d))

#%% exercice 4.1

def compte_lettres(s):
    d = {}
    for x in s:
        if x in d:
            d[x] = d[x] + 1
        else:
            d[x] = 1
    return d

# test
print(compte_lettres("BCPST"))
print(compte_lettres("VERSAILLES"))
print(compte_lettres("Ça marche même avec TOUS les caractères !!!"))
# à vous !
print(compte_lettres(""))

#%% exercice 4.2

# classique classique classique, aucune excuse !!!
# version récursive
def factoriel(n):
    if n == 0:
        return 1
    else:
        return n * factoriel(n-1)

def nombre_anagrammes(s):
    d = compte_lettres(s)
    numerateur = factoriel(len(s))
    denominateur = 1
    for v in d.values():
        denominateur = denominateur * factoriel(v)
    return numerateur // denominateur

# test
print(nombre_anagrammes("BCPST"))
print(nombre_anagrammes("ANANAS"))
# à vous !
print(nombre_anagrammes(""))

#%% exercice 5.1

chiffres = {"zéro": 0, "un": 1, "deux": 2, "trois": 3, "quatre": 4, "cinq": 5, "six": 6, "sept": 7, "huit": 8, "neuf": 9}

def traduit(L):
    for c in L:
        print(chiffres[c])

# test
traduit(["deux", "huit", "trois"])

#%% exercice 5.2

def nombre(L):
    N = 0
    for c in L:
        N = 10 * N + chiffres[c]
    return N

# test
print(nombre(["deux", "huit", "trois"]))

#%% exercice 5.3

def nombre(s):
    N = 0
    L = s.split()
    for c in L:
        x = chiffres[c]
        N = 10 * N + chiffres[c]
    return N

# test
print(nombre("deux huit trois"))

#%% exercice 6.1

def identité(n):
    # en compréhension, c'est facile !
    return {(i, i): 1 for i in range(n)}

# test
print(identité(5))

#%% exercice 6.2 et 6.3

def somme(A, B):
    # matrice nulle
    S = {}
    # copie de A dedans
    for (i, j) in A.keys():
        S[(i, j)] = A[(i, j)]
    # somme B dedans
    for (i, j) in B.keys():
        if (i, j) in S:
            S[(i, j)] = S[(i, j)] + B[(i, j)]
        else:
            S[(i, j)] = B[(i, j)]
    return S

def produit(A, B):
    # matrice nulle
    P = {}
    for (i, k) in A.keys():
        for (k2, j) in B.keys():
            if k == k2:
                # le produit va se sommer dans P[(i, j)]
                if (i, j) in P:
                    P[(i, j)] = P[(i, j)] + A[(i, k)] * B[(k, j)]
                else:
                    P[(i, j)] = A[(i, k)] * B[(k, j)]
    return P

# test : matrices 3×3 au hasard en choisissant au hasard si on remplit le coefficient ou non
from random import randint
A = {(i, j): randint(-5, 5) for i in range(3) for j in range(3) if randint(1, 3) <= 2}
B = {(i, j): randint(-5, 5) for i in range(3) for j in range(3) if randint(1, 3) <= 2}
print("A =", A)
print("B =", B)
print("A+B =", somme(A, B))
print("A×B =", produit(A, B))

#%% exercice 6.4

def est_triangulaire_supérieure(A):
    for (i, j) in A.keys():
        if i > j:
            if A[(i, j)] != 0:
                return False
    return True

# test
A = {(0, 0): 1, (0, 1): 4, (1, 0): 3, (1, 1): -2}
print(A)
print(est_triangulaire_supérieure(A))
B = {(0, 0): 1, (0, 1): 4, (1, 1): -2}
print(B)
print(est_triangulaire_supérieure(B))
C = {(0, 0): 1, (0, 1): 4, (1, 0): 0, (1, 1): -2}
print(C)
print(est_triangulaire_supérieure(C))
D = {(0, 0): 0, (0, 1): 4, (1, 0): 3, (1, 1): -2}
print(D)
print(est_triangulaire_supérieure(D))
