# TP 07 correction : Révisions et consolidation 1
# BCPST1B 2026-2027
# Lycée Hoche, Versailles
# L.-C. LEFÈVRE

#%% exercice 1.1

def arbre(t):
    if t < 0.5:
        print("arbrisseau")
    elif t < 4:
        print("arbuste")
    elif t < 8:
        print("petit arbre")
    elif t < 15:
        print("arbre moyen")
    else:
        print("grand arbre")

# test
arbre(3.8)
arbre(18)

#%% exercice 1.2.i

def u_suite(n):
    u = 1
    for i in range(n):
        u = 8 / (2 + u)
    return u

# test
for i in range(11):
    print(u_suite(i))

#%% exercice 1.2.ii

def u_liste(n):
    L = [0] * n
    L[0] = 1
    for i in range(1, n):
        L[i] = 8 / (2 + L[i-1])
    return L

# test
print(u_liste(11))

#%% exercice 1.3

def somme(n):
    S = 0
    for k in range(1, n+1):
        S = S + 1 / k**2
    return S

# test
for i in range(1, 11):
    print(somme(i))

#%% exercice 2.1

def tribonacci(n):
    # u, v, w représentent T(i), T(i+1), T(i+2) en entrant dans la boucle
    u = 0
    v = 1
    w = 1
    for i in range(n):
        # terme suivant
        t = u + v + w
        # avancer d'un cran
        u = v
        v = w
        w = t
    # à la fin, u est bien T(n), v est T(n+1) et w est T(n+2)
    return u

# test
for i in range(11):
    print(tribonacci(i))

#%% exercice 2.2

def tribonacci_liste(n):
    L = [0] * n
    L[0] = 0
    L[1] = 1
    L[2] = 1
    for i in range(3, n):
        L[i] = L[i-1] + L[i-2] + L[i-3]
    return L

# test
print(tribonacci_liste(11))

#%% exercice 3.1

# z[0] est la partie réelle
# z[1] est la partie imaginaire

def somme(z, w):
    a = z[0]
    b = z[1]
    c = w[0]
    d = w[1]
    return [a+c, b+d]

# test
print(somme([1, 3], [4, -5]))

#%% exercice 3.2

def produit(z, w):
    a = z[0]
    b = z[1]
    c = w[0]
    d = w[1]
    # avoir sous les yeux le développement de (a+bi)*(c+di)
    return [a*c - b*d, a*d + b*c]

# test
print(produit([1, 3], [4, -5]))

#%% exercice 3.3

def puissance(z, n):
    assert n >= 0, "Cette fonction donne le bon résultat seulement si n est positif."
    # u = 1 (le 1 des nombres complexes qui nous sommes en train de modéliser)
    u = [1, 0]
    for i in range(n):
        u = produit(z, u)
    return u

# test
z = [1, 2]
for i in range(7):
    print(puissance(z, i))

#%% exercice 4

def compte_points(r):
    c = 0
    for n in range(-r, r+1):
        for m in range(-r, r+1):
            if n**2 + m**2 <= r**2:
                c = c + 1
    # directement la version modifiée
    return c / r**2

# tests
print(compte_points(10))
print(compte_points(100))
print(compte_points(1000))
print(compte_points(5000))

#%% exercice 5.1

def tous_chiffres(L):
    for i in range(len(L)):
        # test de la condition contraire…
        if L[i] < 0 or L[i] > 9:
            return False
    return True

# tests
print(tous_chiffres([8, 3, 7, 2]))
print(tous_chiffres([8, 3, -1, 2]))
print(tous_chiffres([8, 3, 1, 13]))

#%% exercice 5.2

def sont_consécutifs(L):
    for i in range(len(L)-1):
        if L[i+1] != L[i] + 1:
            return False
    return True

# tests
print(sont_consécutifs([13, 14, 15, 16]))
print(sont_consécutifs([13, 14, 15, 17]))

#%% exercice 5.3

def est_symétrique(L):
    n = len(L)
    for i in range(n):
        if L[i] != L[n-1-i]:
            return False
    return True

# tests
print(est_symétrique([4, 5, 8, 2, 8, 5, 4]))
print(est_symétrique([3, 7, 7, 3]))
print(est_symétrique([3, 7, 5, 8, 6, 7, 3]))

#%% exercice 6.1

def miroir(L):
    n = len(L)
    M = [0] * n
    for i in range(n):
        M[i] = L[n-1-i]
    return M

# test
L = [3, 7, 1, 6, 2]
print("L =", L)
print(miroir(L))

# variante : M = [L[n-1-i] for i in range(n)]

#%% exercice 6.2

def sommes_cumul(L):
    n = len(L)
    if n == 0:
        return []
    # c'est ainsi que C[i] cumule les sommes précédentes avec L[i]
    C = [0] * n
    C[0] = L[0]
    for i in range(1, n):
        C[i] = C[i-1] + L[i]
    return C

# test
L = [2, 4, 3, 5, 3, 5]
print("L =", L)
print(sommes_cumul(L))

#%% exercice 6.3

def somme(L, M):
    n = len(L)
    assert n == len(M), "Les deux listes doivent être de la même longueur"
    S = [0] * n
    for i in range(n):
        S[i] = L[i] + M[i]
    return S

# test
print(somme([3, 7, 1], [2, 8, 1]))

# variante : S = [L[i] + M[i] for i in range(n)]

#%% exercice 7.1

alphabet = "abcdefghijklmnopqrstuvwxyz"

def numéro(x):
    for i in range(26):
        if alphabet[i] == x:
            return i
    return None

#%% exercice 7.2

# attention pour x, y, z
def code_caractère(x):
    i = numéro(x)
    # on ne code pas les caractères autres que ces 26 lettres
    if i == None:
        return x
    else:
        j = i + 3
        # si on dépasse 26, redescendre de 26
        if j >= 26:
            j = j - 26
        return alphabet[j]

#%% exercice 7.3

# facile une fois les deux fonctions précédentes écrites
def code(s):
    n = len(s)
    C = []
    for i in range(n):
        x = s[i]
        C.append(code_caractère(x))
    return "".join(C)

# tests
s = "bcpst"
print("s =", s)
print(code(s))
s = "python"
print("s =", s)
print(code(s))
s = "j'aime bien les tp python"
print("s =", s)
print(code(s))
