Algorithmique et Python

Écrire, lire et expliquer des programmes liés aux notions de Terminale.

Télécharger le PDF

Pourquoi étudier l'algorithmique en maths ?

De quoi parle-t-on ?

L'algorithmique est la science de la résolution méthodique de problèmes. En Terminale, Python est l'outil qui permet de mettre en œ uvre les algorithmes pour résoudre des problèmes que le calcul à la main ne peut pas traiter : trouver un zéro de fonction, approcher une intégrale, simuler des expériences aléatoires, résoudre des équations différentielles numériquement.

Les 7 algorithmes du programme

Schéma : Les 7 algorithmes du programme

L'idée directrice

Schéma : L'idée directrice

Cours Python : Les bases pour débutants

Les variables : des boîtes avec une étiquette

x = 5           # la boîte x contient 5
nom = "Alice"   # la boîte nom contient le texte "Alice"
pi = 3.14159    # la boîte pi contient 3.14159

x = x + 3       # on prend la valeur de x (5), on ajoute 3,
                 # et on remet le résultat (8) dans x
print(x)         # affiche 8

Les types de données

Les opérations de calcul

Afficher et lire : print et input

x = 42
print(x)                    # affiche : 42
print("La valeur est", x)   # affiche : La valeur est 42
print(f"x vaut {x}")        # affiche : x vaut 42 (f-string)
print(f"x² = {x**2}")       # affiche : x² = 1764

Les comparaisons et les booléens

La conditionnelle : if / elif / else

note = 14

if note >= 16:
    print("Très bien")       # exécuté si note >= 16
elif note >= 12:
    print("Bien")            # exécuté si 12 <= note < 16
elif note >= 10:
    print("Passable")        # exécuté si 10 <= note < 12
else:
    print("Insuffisant")     # exécuté si note < 10

# Ici, affiche "Bien" car 14 >= 12 et 14 < 16

La boucle for : répéter un nombre connu de fois

# Affiche 0, 1, 2, 3, 4 (5 valeurs, de 0 à 4)
for i in range(5):
    print(i)

# Affiche 1, 2, 3, 4, 5 (de 1 à 5)
for i in range(1, 6):       # ATTENTION : 6 est exclu !
    print(i)

# Affiche 0, 2, 4, 6, 8 (de 0 à 8, de 2 en 2)
for i in range(0, 10, 2):
    print(i)

La boucle while : répéter tant qu'une condition est vraie

# Trouver le plus petit n tel que 2^n > 1 000 000
n = 0
while 2**n <= 1000000:    # tant que 2^n ≤ 1 000 000
    n = n + 1             # passer au n suivant
print(n)                  # affiche 20 (car 2^20 = 1 048 576)

Comprendre le mécanisme :

Tour\(n\)\(2^n\)
01 \(\leqslant\) 1 000 000 \(\to\) on continue
112 \(\leqslant\) 1 000 000 \(\to\) on continue
224 \(\leqslant\) 1 000 000 \(\to\) on continue
\(\vdots\)\(\vdots\)\(\vdots\)
1919524 288 \(\leqslant\) 1 000 000 \(\to\) on continue
20201 048 576 \(>\) 1 000 000 \(\to\) on sort !

Les fonctions : créer ses propres outils

# DÉFINIR la fonction (rien ne s'exécute encore)
def carre(x):
    return x ** 2       # renvoie x²

# APPELER la fonction (maintenant ça s'exécute)
resultat = carre(5)     # resultat = 25
print(carre(3))         # affiche 9
print(carre(7) + 1)     # affiche 50
import math               # OBLIGATOIRE pour utiliser les fonctions maths

def f(x):
    return x**2 - 3*x + 1          # f(x) = x² - 3x + 1

def g(x):
    return math.exp(x) - 2*x       # g(x) = e^x - 2x

def h(x):
    return math.log(x) + math.sqrt(x)  # h(x) = ln(x) + √x

def derive_approx(f, x, h=1e-6):
    return (f(x + h) - f(x)) / h   # f'(x) ≈ [f(x+h) - f(x)] / h

# Appels :
print(f(2))          # 4 - 6 + 1 = -1
print(g(0))          # 1 - 0 = 1
print(h(1))          # 0 + 1 = 1

Les listes : stocker plusieurs valeurs

# Créer une liste
L = [10, 20, 30, 40, 50]

# Lire un élément (ATTENTION : on compte à partir de 0 !)
print(L[0])     # 10  (premier élément)
print(L[2])     # 30  (troisième élément)
print(L[-1])    # 50  (dernier élément)
print(len(L))   # 5   (nombre d'éléments)

# Ajouter un élément à la fin
L.append(60)    # L = [10, 20, 30, 40, 50, 60]

# Modifier un élément
L[1] = 99       # L = [10, 99, 30, 40, 50, 60]
# Liste des carrés de 0 à 9
carres = []                    # liste vide
for k in range(10):
    carres.append(k**2)
print(carres)   # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# Même chose en UNE ligne (compréhension de liste)
carres = [k**2 for k in range(10)]

# Fonctions utiles sur les listes
print(sum(carres))    # 285 (somme)
print(max(carres))    # 81  (maximum)
print(min(carres))    # 0   (minimum)

Le module random : simuler le hasard

import random

# Nombre décimal aléatoire entre 0 (inclus) et 1 (exclu)
x = random.random()          # ex: 0.7234...

# Entier aléatoire entre a et b (les deux inclus)
d = random.randint(1, 6)     # simule un dé : 1, 2, 3, 4, 5 ou 6

# Choisir un élément au hasard dans une liste
couleur = random.choice(["rouge", "bleu", "vert"])

Récapitulatif : les structures à connaître au bac

Les algorithmes du programme

Algorithme de dichotomie (TVI)

def dichotomie(f, a, b, eps):
    """Retourne une valeur approchée d'un zéro de f sur [a,b]."""
    while b - a > eps:
        m = (a + b) / 2
        if f(a) * f(m) <= 0:
            b = m
        else:
            a = m
    return (a + b) / 2

Méthode d'Euler (équations différentielles)

def euler(f, t0, y0, h, n):
    """Méthode d'Euler : n pas de taille h."""
    T = [t0]
    Y = [y0]
    t, y = t0, y0
    for k in range(n):
        y = y + h * f(t, y)
        t = t + h
        T.append(t)
        Y.append(y)
    return T, Y

Sommes de Riemann (intégrales)

def riemann_gauche(f, a, b, n):
    h = (b - a) / n
    return h * sum(f(a + k * h) for k in range(n))

def riemann_droite(f, a, b, n):
    h = (b - a) / n
    return h * sum(f(a + k * h) for k in range(1, n + 1))

def riemann_milieux(f, a, b, n):
    h = (b - a) / n
    return h * sum(f(a + (k + 0.5) * h) for k in range(n))

Simulation aléatoire et loi des grands nombres

import random

# Pile ou Face (Bernoulli de paramètre 0.5)
def bernoulli(p):
    return 1 if random.random() < p else 0

# Simuler n lancers et calculer la fréquence
def frequence(p, n):
    return sum(bernoulli(p) for _ in range(n)) / n

print(frequence(0.5, 10000))   # ≈ 0.50 (LGN)
import random
import matplotlib.pyplot as plt

def loi_grands_nombres(p, n):
    """Trace la convergence de la fréquence vers p."""
    X = []
    S = 0
    for k in range(1, n + 1):
        S += bernoulli(p)
        X.append(S / k)
    plt.plot(X, linewidth=0.8)
    plt.axhline(y=p, color='red', linestyle='--')
    plt.xlabel('n')
    plt.ylabel('Fréquence')
    plt.title('Loi des grands nombres')
    plt.show()

loi_grands_nombres(0.3, 10000)
def binomiale(n, p):
    """Simule X ~ B(n, p)."""
    return sum(bernoulli(p) for _ in range(n))

# Histogramme de 10000 simulations de B(20, 0.3)
echantillon = [binomiale(20, 0.3) for _ in range(10000)]
plt.hist(echantillon, bins=range(22), density=True,
         edgecolor='black', alpha=0.7)
plt.title('Histogramme B(20, 0.3)')
plt.show()

Suites récurrentes : calcul de termes et recherche de seuil

def termes_suite(f, u0, n):
    """Retourne la liste [u_0, u_1, ..., u_n]."""
    U = [u0]
    u = u0
    for k in range(n):
        u = f(u)
        U.append(u)
    return U

# Exemple : u_{n+1} = √(2 + u_n), u_0 = 0
import math
U = termes_suite(lambda u: math.sqrt(2 + u), 0, 20)
print(U[-1])   # ≈ 2.0 (la suite converge vers 2)
def seuil(f, u0, M):
    """Retourne le plus petit n tel que u_n > M."""
    u = u0
    n = 0
    while u <= M:
        u = f(u)
        n += 1
    return n

# Exemple : u_{n+1} = 1.05 * u_n (croissance 5
# Combien d'années pour dépasser 200 ?
n = seuil(lambda u: 1.05 * u, 100, 200)
print(n)   # 15 (il faut 15 ans pour doubler)

Recherche d'extremum et tri

def maximum_balayage(f, a, b, n):
    """Maximum approché de f sur [a,b] avec n points."""
    h = (b - a) / n
    x_max = a
    y_max = f(a)
    for k in range(1, n + 1):
        x = a + k * h
        y = f(x)
        if y > y_max:
            x_max = x
            y_max = y
    return x_max, y_max

# Exemple : maximum de f(x) = x * e^(-x) sur [0, 5]
import math
xm, ym = maximum_balayage(lambda x: x * math.exp(-x), 0, 5, 10000)
print(f"Max en x = {xm:.4f}, f(x) = {ym:.4f}")
# ≈ x = 1.0000, f(x) = 0.3679 (max théorique en x = 1)

Calcul de coefficients binomiaux et triangle de Pascal

def pascal(n):
    """Retourne le triangle de Pascal jusqu'à la ligne n."""
    T = [[1]]
    for k in range(1, n + 1):
        ligne = [1]
        for j in range(1, k):
            ligne.append(T[k-1][j-1] + T[k-1][j])
        ligne.append(1)
        T.append(ligne)
    return T

# Coefficients binomiaux C(10, k)
T = pascal(10)
print(T[10])   # [1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
import math

def binom(n, k):
    """C(n, k) = n! / (k! * (n-k)!)"""
    return math.factorial(n) // (math.factorial(k) * math.factorial(n - k))

# Ou directement : math.comb(n, k) (Python 3.8+)
print(math.comb(10, 3))   # 120

Visualisation graphique

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-2, 4, 1000)
y = x**2 - 3*x + 1

plt.figure(figsize=(8, 5))
plt.plot(x, y, color='steelblue', linewidth=2, label=r'$f(x)=x^2-3x+1$')
plt.axhline(0, color='black', linewidth=0.5)
plt.axvline(0, color='black', linewidth=0.5)
plt.grid(alpha=0.3)
plt.legend(fontsize=12)
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Graphe de f')
plt.show()
import numpy as np
import matplotlib.pyplot as plt

def euler_plot(f, t0, y0, h, n):
    T, Y = euler(f, t0, y0, h, n)
    plt.plot(T, Y, 'o-', markersize=2, label=f'Euler (h={h})')

# y' = -2y + 6, y(0) = 1
f = lambda t, y: -2*y + 6
euler_plot(f, 0, 1, 0.5, 10)     # pas grossier
euler_plot(f, 0, 1, 0.1, 50)     # pas moyen
euler_plot(f, 0, 1, 0.01, 500)   # pas fin

# Solution exacte
t = np.linspace(0, 5, 200)
plt.plot(t, -2*np.exp(-2*t) + 3, 'r--', linewidth=2, label='Exacte')
plt.legend()
plt.title("Méthode d'Euler : effet du pas h")
plt.show()

Résumé : quel algorithme pour quel problème ?

Boîte à outils : Réflexes pour le bac