# TP 04 correction : Boucles for
# BCPST1B 2026-2027
# Lycée Hoche, Versailles
# L.-C. LEFÈVRE

#%% partie I

nom = "L.-C. LEFÈVRE"
for _ in range(3):
    print("Au travail", nom)

#%% exercice 1

def kilomètres(n):
    for i in range(1, n+1):
        print(i, "kilomètres à pieds, ça use, ça use,")
        print(i, "kilomètres à pieds, ça use les souliers.")

kilomètres(10)

#%% partie I exemple

def puissance2(n):
    u = 1
    for i in range(n):
        u = 2 * u
    return u

# test
print(puissance2(5))

#%% exercice 2

def suite(n):
    # u représente u(i) en début de boucle
    u = 2
    for i in range(n):
        # u devient u(i+1)
        u = 1 + 1/u
    return u

# test
for n in range(10):
    print(suite(n))

#%% exercice 3

def factoriel(n):
    # u représente u(i) en début de boucle
    u = 1
    for i in range(n):
        # u devient u(i+1) (en fonction de u(i))
        u = (i+1) * u
    return u

# test
for n in range(10):
    print(factoriel(n))

#%% exercice 3 variante

def factoriel2(n):
    # u représente u(i-1) en début de boucle
    u = 1
    for i in range(1, n+1):
        # u devient u(i) (en fonction de u(i-1))
        u = i * u
    return u

# test
for n in range(10):
    print(factoriel2(n))

#%% exercice 4

def fibonacci(n):
    # u représente F(i) en début de boucle
    u = 0
    # v représente F(i+1) en début de boucle
    v = 1
    for i in range(n):
        # terme suivant
        t = u + v
        # puis u devient F(i+1) et v devient F(i+2)
        u = v
        v = t
    return u

# test
for n in range(10):
    print(fibonacci(n))

#%% exercice 5

def somme_cubes(n):
    # variable accumulatrice
    S = 0
    for i in range(1, n+1):
        # somme des i**3, pour i de 1 à n (bornes incluses)
        S = S + i**3
    return S

# test : comparer avec la formule proposée
for i in range(10):
    a = somme_cubes(i)
    b = i**2 * (i+1)**2 / 4
    print(i, a, b)

#%% exercice 6

# version naïve
def somme_inverse_factoriel(n):
    S = 0
    # somme pour i de 0 à n, bornes incluses
    for i in range(0, n+1):
        S = S + 1 / factoriel(i)
    return S

# test : le résultat converge vers e
print(somme_inverse_factoriel(10))

#%% exercice 6, amélioration

# Mieux : on peut éviter de recalculer factoriel depuis le début dans la boucle
# en introduisant u qui calcule factoriel au fur et à mesure.
# C'est une fusion des deux fonctions.
def somme_inverse_factoriel_2(n):
    S = 0
    u = 1
    for i in range(0, n+1):
        # somme
        S = S + 1 / u
        # puis calcul du factoriel suivant
        u = (i+1) * u
    return S

# test
print(somme_inverse_factoriel_2(10))

#%% exercice 7

#%% parcourir les lignes
for i in range(3):
    for j in range(3):
        print("i =", i, "j =", j)

#%% parcourir les colonnes
for j in range(3):
    for i in range(3):
        print("i =", i, "j =", j)

#%% exercice 8.1

def table():
    for i in range(1, 11):
        for j in range(1, 11):
            print(i, "*", j, "=", i*j)

table()

#%% exercice 8.2

def table_carré():
    for i in range(1, 11):
        for j in range(1, 11):
            # fin : pas de saut de ligne mais un espace
            print(i * j, end=" ")
        # saut de ligne
        print()

table_carré()

#%% exercice 8.3

def table_carré_joli():
    for i in range(1, 11):
        for j in range(1, 11):
            x = i * j
            print(f"{x:4d}", end="")
        print()

table_carré_joli()

#%% exercice 9

def pythagore(N):
    for a in range(1, N+1):
        for b in range(1, N+1):
            for c in range(N+1):
                if a**2 + b**2 == c**2:
                    print(a, b, c)

pythagore(30)

# bonus : remplacer la deuxième boucle par for b in range(1, a+1) pour avoir b <= a

#%% partie III

t = ("mathématiques", "physique-chimie", "SVT")
for x in t:
    print("J'aime le cours de", x, "car je suis en BCPST.")

#%% exercice 10

for n in (1, 2, 3, 5, 10, 20):
    print(somme_inverse_factoriel(n))

#%% exercice 11

def quotients(n):
    assert n >= 1
    # on recopie Fibonacci
    u = 0
    v = 1
    for i in range(n):
        t = u + v
        u = v
        v = t
    # fin : u est F(n), v est F(n+1)
    # et t est F(n+2) si on a fait au moins un passage dans la boucle (n >= 1)
    return (v/u, t/v)

for n in range(1, 11):
    print(quotients(n))

# les quotients convergent vers le nombre d'or, encadrent la limite, et leur ordre alterne

#%% exercice 12

def type_lettres(s):
    for x in s:
        if x == "a" or x == "e" or x == "i" or x == "o" or x == "u" or x == "y":
            print("voyelle")
        else:
            print("consonne")

# test
type_lettres("informatique")
