Aller au contenu

Exercices corrigés — Algorithmique et programmation Python (Seconde)

Quatre niveaux de difficulté, du plus simple au plus exigeant. Chaque exercice a sa correction détaillée, étape par étape.

8 exercices, classés par difficulté croissante.

Exercice 1 Découverte

Que renvoie la fonction suivante pour n = 5 ? Justifier en donnant les valeurs successives de r.

def mystere(n):
    r = 1
    for k in range(n):
        r = 2*r
    return r
Voir la correction
Correction détaillée

range(5) produit les cinq valeurs 0, 1, 2, 3, 4 : le corps de la boucle est exécuté cinq fois, quelle que soit la valeur de k, qui ne sert qu'à compter.
À chaque passage, r est doublé : au départ r = 1, puis 2, 4, 8, 16 et enfin 32.
La fonction renvoie 32, c'est-à-dire 25 : après n passages, r vaut 2n (c'est l'invariant de boucle). mystere(0) renverrait 1 = 20, la boucle n'étant pas exécutée.
Un tableau de trace (colonne k, colonne r) est la méthode la plus sûre pour lire un tel programme ; ici il tient en une ligne par passage.

Exercice 2 Découverte

On exécute les instructions suivantes. Donner la valeur de chaque variable à la fin, en précisant son type.

x = 3
x = x + 2
x = 4 * x
y = x % 6
z = x // 6
test = (y == 2) and (z > 5)
Voir la correction
Correction détaillée

ligne 1 : x reçoit 3. Ligne 2 : on calcule x + 2 = 5 avec l'ancienne valeur, puis on stocke 5 dans x ; le signe = est une affectation, pas une égalité. Ligne 3 : x reçoit 4 × 5 = 20.
Ligne 4 : % donne le reste de la division entière, 20 = 3 × 6 + 2, donc y = 2. Ligne 5 : // donne le quotient entier, z = 3.
Ligne 6 : y == 2 est vrai (True), z > 5 est faux (False) puisque z = 3 ; un « et » n'est vrai que si les deux conditions le sont, donc test = False.
Types finaux : x, y et z sont des entiers (int), test est un booléen (bool). Attention à ne pas confondre = (affecter) et == (comparer), ni / (division décimale, 206 ≈ 3,33) avec //.

Exercice 3 Application

Écrire une fonction determinant(x, y, xp, yp) qui renvoie le déterminant des vecteurs u(x ; y) et v(xp ; yp). L'utiliser pour tester si u(6 ; −9) et v(−4 ; 6) sont colinéaires.

Voir la correction
Correction détaillée

le déterminant de u(x ; y) et v(x' ; y') vaut xy' − yx'. La fonction traduit cette formule, avec quatre arguments et un return :

def determinant(x, y, xp, yp):
    return x*yp - y*xp

Test : determinant(6, -9, -4, 6) calcule 6 × 6 − (−9) × (−4) = 36 − 36 = 0. Le déterminant est nul, donc les vecteurs sont colinéaires (en fait u = −1,5 v).
On peut en déduire une fonction booléenne colineaires(x, y, xp, yp) qui renvoie determinant(x, y, xp, yp) == 0. Avec des coordonnées décimales, on préférera tester abs(determinant(...)) < 1e-9, car les calculs flottants ne tombent pas toujours exactement sur 0.
Rappel : return renvoie une valeur réutilisable ; print ne ferait que l'afficher.

Exercice 4 Application

Un musée propose l'entrée à 5 € pour les moins de 12 ans, 8 € de 12 à 17 ans inclus, et 12 € à partir de 18 ans. Écrire une fonction tarif(age) qui renvoie le prix, puis donner les résultats de tarif(11), tarif(12) et tarif(18).

Voir la correction
Correction détaillée

on enchaîne trois cas avec if, elif et else, en testant les conditions dans l'ordre croissant des âges :

def tarif(age):
    if age < 12:
        return 5
    elif age < 18:
        return 8
    else:
        return 12

tarif(11) : 11 < 12 est vrai, la fonction renvoie 5. tarif(12) : 12 < 12 est faux, on passe au elif, 12 < 18 est vrai, elle renvoie 8. tarif(18) : les deux tests sont faux, on arrive au else, elle renvoie 12.
Le second test n'a pas besoin d'écrire age >= 12 : quand on l'atteint, on sait déjà que la première condition était fausse. Les cas limites 12 et 18 sont les plus importants à tester : ils vérifient les inégalités strictes ou larges. Une fois qu'un return est exécuté, la fonction s'arrête.

Exercice 5 Maîtrise

Compléter une fonction plus_grand_multiple(a, b) qui renvoie le plus grand multiple de a inférieur ou égal à b, pour a > 0 et b ≥ 0.

Voir la correction
Correction détaillée

le quotient entier b // a indique combien de fois a « rentre » dans b ; le multiple cherché est ce quotient multiplié par a :

def plus_grand_multiple(a, b):
    return (b // a) * a

Exemple : pour a = 7 et b = 50, 50 // 7 vaut 7 (car 7 × 7 = 49 ≤ 50 < 56), et la fonction renvoie 49. Autre écriture équivalente : b - b % a, puisque 50 − 50 % 7 = 50 − 1 = 49.
Cas limites : si b est déjà un multiple de a, par exemple a = 7 et b = 49, 49 // 7 * 7 vaut 49, le nombre lui-même ; si b < a, le quotient vaut 0 et la fonction renvoie 0, qui est bien le plus grand multiple de a inférieur ou égal à b.
L'hypothèse a > 0 évite une division par zéro et garantit le sens du quotient entier.

Exercice 6 Maîtrise

On veut trouver le premier entier n tel que 1,1n > 2 avec le programme : n = 0 ; p = 1 ; while p <= 2 : n = n + 1. Expliquer le problème, corriger le programme et donner le résultat.

Voir la correction
Correction détaillée

la variable p, censée représenter 1,1n, n'est jamais modifiée dans la boucle : la condition p <= 2 reste toujours vraie et la boucle ne s'arrête jamais. C'est une boucle infinie, le défaut le plus fréquent d'une boucle while.
Correction : à chaque passage, il faut multiplier p par 1,1 en même temps qu'on augmente n :

n = 0
p = 1
while p <= 2:
    p = p * 1.1
    n = n + 1
print(n)

Déroulement : p prend les valeurs 1,1 ; 1,21 ; 1,331 ; 1,4641 ; 1,6105 ; 1,7716 ; 1,9487 ; 2,1436. Au huitième passage, p dépasse 2 et n vaut 8 : la boucle s'arrête. Le programme affiche 8, et l'on vérifie 1,17 ≈ 1,95 ≤ 2 < 1,18 ≈ 2,14.
Terminaison : comme 1,1 > 1, les puissances 1,1n finissent toujours par dépasser 2. Avec une raison inférieure à 1, la boucle corrigée serait de nouveau infinie.

Exercice 7 Challenge

On adapte l'algorithme du cours pour encadrer 3 au dixième : pas = 0.1 ; x = 0 ; while (x + pas)**2 <= 3 : x = x + pas. Quelles valeurs successives prend x ? Quel encadrement obtient-on ? Comment obtenir un encadrement au centième ?

Voir la correction
Correction détaillée

la boucle avance x de 0,1 en 0,1 tant que le carré du nombre suivant ne dépasse pas 3. On teste donc successivement (0,1)2, (0,2)2, … : x prend les valeurs 0 ; 0,1 ; 0,2 ; … ; 1,7.
Pour x = 1,7, le nombre suivant est 1,8 et 1,82 = 3,24 > 3 : la condition devient fausse, la boucle s'arrête avec x = 1,7. On a 1,72 = 2,89 ≤ 3 < 3,24 = 1,82, et comme la fonction carré est croissante sur les positifs : 1,7 ≤ 3 < 1,8.
C'est un encadrement d'amplitude 0,1 ; en effet 3 ≈ 1,732. Pour un encadrement au centième, on prend pas = 0.01 : la boucle s'arrête à x = 1,73, car 1,732 = 2,9929 ≤ 3 < 3,0276 = 1,742, d'où 1,73 ≤ 3 < 1,74.
Remarque pratique : les additions répétées de 0,1 en flottants accumulent de petites erreurs (0,1 + 0,1 + 0,1 n'est pas exactement 0,3 en machine) ; pour de nombreuses étapes, on préfère calculer x comme k × pas avec k entier.

Exercice 8 Challenge

Écrire une fonction frequence_au_moins_5(n) qui simule n lancers d'un dé équilibré et renvoie la fréquence des résultats supérieurs ou égaux à 5. Quelle valeur attend-on pour n grand ?

Voir la correction
Correction détaillée

randint(1, 6) renvoie un entier entre 1 et 6 inclus, chaque face ayant la même probabilité : c'est le modèle du dé équilibré. On compte les tirages qui valent 5 ou 6 :

from random import randint

def frequence_au_moins_5(n):
    compteur = 0
    for i in range(n):
        if randint(1, 6) >= 5:
            compteur = compteur + 1
    return compteur / n

Deux faces sur six conviennent, donc la probabilité théorique est 26 = 13 ≈ 0,333. Pour n grand (10 000 par exemple), la fréquence renvoyée est proche de 0,333, avec une valeur différente à chaque exécution : c'est la loi des grands nombres, la fréquence observée se rapprochant de la probabilité sans jamais la garantir.
Erreurs à éviter : tirer le dé une seule fois avant la boucle (le même résultat serait compté n fois), oublier d'initialiser le compteur, ou diviser par 6 au lieu de n.