#### Par Pierre Béaur. 24/09/2026.
#### Séance 03

### Exercice 1
## 1.

def prod(tab):
    p = 1
    for i in range(len(tab)):
        p *= tab[i]
    return p

## 2.

def racines(n):
    t = []
    for i in range(n+1):
        t += [i**(1/2)]
    return t

## 3.

def plus_de_pairs(tab):
    a,b = 0,0
    for i in range(len(tab)):
        if tab[i]%2==0:
            a += 1
        else:
            b +=1
    return a >= b

### Exercice 2

# int
# float
# float
# string
# string
# string
# string (c'est valide)
# string list
# string
# (string*int) list
# int list list
# mal typé : en soi, list

### Exercice 3
## 2.

# Non, les strings ne sont pas mutables.

### Exercice 4
## 1.

def sans_la_fin(texte):
    t = ""
    for i in range(len(texte)-1):
        t += texte[i]
    return t

## 2.

def est_dedans(lettre,texte):
    for i in range(len(texte)):
        if lettre==texte[i]:
            return True
    return False

## 3.

def begayant_string(s):
    t = ""
    for i in range(len(s)):
        t += s[i]+s[i]
    return t

### Exercice 5

def nb_voyelles(str):
    voy = "aeiouy"
    c = 0
    for i in range(len(str)):
        if est_dedans(str[i],voy):
            c += 1
    return c

### Exercice 6
## 1.

def lettres(texte):
    t = []
    for i in range(len(texte)):
        if not est_dedans(texte[i],t):
            t += [texte[i]]
    return t

## 2.

# La fonction suivante n'est pas très efficace.
# À l'aide de dictionnaires, on peut faire beaucoup mieux.

def lettre_la_plus_commune(texte):
    l = lettres(texte)
    m = l[0]
    cm = -1
    for i in range(len(l)):
        c = 0
        le = l[i]
        for i in range(len(texte)):
            if texte[i]==le:
                c += 1
        if cm < c:
            m = le
            cm = c
    return m

## 3.

def mots(texte):
    t = []
    mot = ""
    for i in range(len(texte)):
        if texte[i] == " ":
            t += [mot]
            mot = ""
        else:
            mot += texte[i]
    return t+[mot]

##4.

def palindrome(mot):
    n = len(mot)
    for i in rangel(len(mot)):
        if mot[i] != mot[n-i-1]:
            return False
    return True

# Techniquement, on vérifie deux fois chaque lettre ; cela ne change rien à la complexité théorique.

### Exercice 8
## 1.

def nb_occurrences(tab):
    d = {}
    for i in range(len(tab)):
        if tab[i] in d:
            d[tab[i]] += 1
        else:
            d[tab[i]] = 1
    return d

## 2.

def moyennes_occurrences(tab):
    d = nb_occurrences(tab)
    s = 0
    for x in d:
        s += d[x]
    return s/len(d)

def moy_occ_v2(tab):
    k = len(nb_occurrences(tab))
    return len(tab)/k

## 3.

def anagramme(m1,m2):
    d1 = nb_occurrences(m1)
    d2 = nb_occurrences(m2)
    for l in d1:
        if (l not in d2) or (d1[l] != d2[l]):
            return False
    return len(m1)==len(m2)

### Exercice 9
## 1.

def union(ens1,ens2):
    u = []
    for i in range(len(ens1)):
        u += [ens1[i]]
    for i in range(len(ens2)):
        if not est_dedans(ens2[i],u):
            u += [ens2[i]]
    return u

def intersection(ens1,ens2):
    u = []
    for i in range(len(ens1)):
        for j in range(len(en2)):
            if ens1[i] == ens2[j]:
                u += [ens1[i]]
    return u

## 2.

def union2(ens1,ens2):
    d = {}
    for x in ens1:
        d[x] = True
    for x in ens2:
        d[x] = True
    return d

def intersection2(ens1,ens2):
    d = {}
    for x in ens1:
        if x in ens2:
            d[x] = True
    return d

### Exercice 10
## 3.

def est_facteur(fac,mot):
    f = len(fac)
    for i in range(len(mot)-f):
        if mot[i:i+f] == fac:
            return True
    return False

## 4.

def est_facteur_emplacement(fac,mot,i):
    f = len(fac)
    for j in range(f):
        if fac[j] != mot[i+j]:
            return False
    return True

def est_facteur_2(fac,mot):
    f = len(fac)
    for i in range(len(mot)-f):
        if est_facteur_emplacement(fac,mot,i):
            return True
    return False

## 5.

# O(|fac| * |mot|)
# correspond au cas où on n'a rien trouvé.

### Exercice 11
## 4.

def copie(t):
    nt = []
    for i in range(len(t)):
        nt+=[t[i]]
    return nt

### Exercice 12
## 1.

def est_trie(tab):
    for i in range(len(tab)-1):
        if tab[i+1] < tab[i]:
            return False
    return True

def indice_minimum(tab,i):
    ind = i
    for j in range(i,len(tab)):
        if tab[ind]>tab[j]:
            ind = j
    return ind

def tri_selection(tab):
    for i in range(len(tab)):
        j = indice_minimum(tab,i)
        tab[i],tab[j] = tab[j],tab[i]
    return tab

### Exercices à la maison

def plus_long_plateau(tab):
    long_max = 0
    ind = -1
    for i in range(len(tab)):
        j = i
        while j < len(tab) and tab[j]==tab[i]:
            j += 1
        long = j-i
        if long > long_max:
            long_max = long
            ind = i
    return ind,ind+long_max-1

def est_trie_couples(t):
    for i in range(len(t)-1):
        if t[i][0]>t[i][1] or t[i][1]>t[i+1][0]:
            return False
    return t[len(t)-1][0]<t[len(t)-1][1]

def aplatir(m):
    t = []
    for i in range(len(m)):
        t += m[i]
    return t

#### Bonus

### Exercice 1
## 1.

def liste_facteurs(mot,n):
    f = []
    for i in range(len(mot)-n):
        if mot[i:i+n] not in f:
            f+=mot[i:i+n]
    return f

## 2.

def nb_facteurs(mot,n):
    return len(liste_facteurs(mot,n))

## 3.
# On rappelle que l'alphabet est binaire.

### Exercice 2
## 1.

def plus_proches(tab):
    d = abs(tab[1]-tab[0])
    for i in range(len(tab)):
        for j in range(len(tab)):
            if i != j and abs(tab[i]-tab[j]) < d:
                x,y = tab[x],tab[y]
                d = abs(tab[i]-tab[j])
    return x,y

## 2.
# O(n^2).

### Exercice 3
## Version dictionnaires

catalogue = {}

def ajouter_meuble(nom,prix):
    catalogue[nom] = prix

catalogue = {"table":250 ,
             "lit" : 550 ,
             "chaise" : 60}

def moyenne_prix():
    c = 0
    for m in catalogue:
        c += catalogue[m]
    return c/len(catalogue)

def liste_meubles():
    t = []
    for m in catalogue:
        t += [m]
    return t

def imprimer_catalogue():
    for m in catalogue:
        print(m + " coûte " + str(catalogue[m]))

def vendre(nom):
    c = catalogue[nom]
    print("vendu ! argent gagné : " + str(c))
    del catalogue[nom]

## Versions tableaux

noms_meubles = []
prix_meubles = []

def ajouter_meuble_2(nom,prix):
    global noms_meubles
    global prix_meubles
    noms_meubles += [nom]
    prix_meubles += [prix]

def moyenne_prix_2():
    global prix_meubles
    return moyenne(prix_meubles)

def liste_meubles_2():
    global noms_meubles
    return noms_meubles

def imprimer_catalogue_2():
    global noms_meubles
    global prix_meubles
    for i in range(len(noms_meubles)):
        print(noms_meubles[i] + " coûte " + str(prix_meubles[i]))

def vendre2(nom):
    global noms_meubles
    global prix_meubles
    ind = -1
    for i in range(len(noms_meubles)):
        if noms_meubles[i] == nom:
            ind = i
    print("vendu ! argent gagné : " + str(prix_meubles[i]))
    noms_meubles = noms_meubles[:i]+noms_meubles[i+1:]
    prix_meubles = prix_meubles[:i]+prix_meubles[i+1:]

### Exercice 4

score = {}

score["dauw"] = 14
score["bonbon"] = 10

score2 = {}

# score2[["d","a","u","w"]] = 14
# score2[["b","o","n","b","o","n"]] = 10

# Ça ne marche pas, car les clés n'ont pas le droit d'être mutables.