Calcul et algorithmique | BTS | Mathématiques
Dernière mise à jour : 21 octobre 2026
if / elif / else |
POUR i DE a À b ⇔ for i in range(a, b+1) |
TANT QUE cond ⇔ while cond |
hiérarchie des complexités : \(O(1) \ll O(\log n) \ll O(n) \ll O(n\log n) \ll O(n^2) \ll O(2^n)\) |
dichotomie : \(n \geq \log_2\!\left(\dfrac{b-a}{\varepsilon}\right)\) itérations.
Un automaticien étudie l'instruction d'affectation à travers le programme Python suivant :
a = 5
b = 3
a = a + b
b = a - b
a = a - b
print(a, b)
1. Complète le tableau de trace en indiquant la valeur de a et de b après chaque ligne.
2. Quel est l'affichage final ? Quel est, selon toi, le rôle de ce petit programme ?
1.
| Instruction exécutée | a | b |
|---|---|---|
a = 5 | 5 | — |
b = 3 | 5 | 3 |
a = a + b | 8 | 3 |
b = a - b | 8 | 5 |
a = a - b | 3 | 5 |
2. L'affichage final est 3 5. Ce programme échange le contenu de deux variables (a et b ont permuté) sans passer par une variable auxiliaire.
Un technicien qualité contrôle le diamètre d'axes usinés. La cote nominale est de 12 mm avec une tolérance de ±0,02 mm.
1. Écris en Python une fonction controle(diametre) qui affiche "ACCEPTÉ" si la pièce est dans la tolérance, "REJETÉ — sous-dimensionné" si elle est trop petite, et "REJETÉ — sur-dimensionné" si elle est trop grande.
2. Donne le résultat de l'appel de cette fonction pour les diamètres mesurés : 11,99 mm ; 12,05 mm ; 12,01 mm.
1.
def controle(diametre):
if 11.98 <= diametre <= 12.02:
print("ACCEPTÉ")
elif diametre < 11.98:
print("REJETÉ — sous-dimensionné")
else:
print("REJETÉ — sur-dimensionné")
2. 11,99 mm ∈ [11,98 ; 12,02] → ACCEPTÉ. 12,05 mm > 12,02 → REJETÉ — sur-dimensionné. 12,01 mm ∈ [11,98 ; 12,02] → ACCEPTÉ.
Un technicien de maintenance relève la température (en °C) d'une enceinte toutes les heures pendant 6 heures :
T = [18.5, 19.2, 20.1, 19.8, 18.9, 19.4]
1. Écris un programme Python utilisant une boucle for pour calculer la somme des valeurs de T, puis la moyenne.
2. Complète le tableau de trace de la variable somme au fil des itérations.
3. Donne la valeur de la moyenne (arrondie au centième).
1.
T = [18.5, 19.2, 20.1, 19.8, 18.9, 19.4]
somme = 0
for i in range(len(T)):
somme = somme + T[i]
moyenne = somme / len(T)
print(f"Moyenne = {moyenne:.2f} °C")
2.
| i | T[i] | somme |
|---|---|---|
| — | — | 0 |
| 0 | 18,5 | 18,5 |
| 1 | 19,2 | 37,7 |
| 2 | 20,1 | 57,8 |
| 3 | 19,8 | 77,6 |
| 4 | 18,9 | 96,5 |
| 5 | 19,4 | 115,9 |
3. \(\text{moyenne} = 115{,}9 / 6 = 19{,}3166\ldots \approx 19{,}32\,\text{°C}\).
Un technicien doit saisir le débit d'une pompe (en L/min), qui doit obligatoirement être strictement compris entre 0 et 500 L/min.
Écris un programme Python qui redemande la saisie tant que la valeur entrée n'est pas valide, en affichant un message d'erreur adapté.
debit = -1
while not (0 < debit < 500):
debit = float(input("Débit (L/min, entre 0 et 500) : "))
if not (0 < debit < 500):
print("Erreur : valeur hors plage.")
print(f"Débit enregistré : {debit} L/min")
La condition du while porte sur la variable modifiée dans le corps de boucle (debit), ce qui garantit que la boucle se termine dès qu'une valeur valide est saisie.
Un ingénieur qualité te transmet la fonction suivante, sans documentation :
def mystere(t):
n = len(t)
m = t[0]
for i in range(1, n):
if t[i] > m:
m = t[i]
return m
1. Trace l'exécution de mystere([12, 45, 7, 68, 23]) en indiquant la valeur de m après chaque itération.
2. Quel est le rôle de cette fonction ? Propose un contexte industriel où elle serait utile.
1.
| i | t[i] | t[i] > m ? | m |
|---|---|---|---|
| — | — | — | 12 (init.) |
| 1 | 45 | oui | 45 |
| 2 | 7 | non | 45 |
| 3 | 68 | oui | 68 |
| 4 | 23 | non | 68 |
La fonction retourne 68.
2. Cette fonction détermine le maximum d'une série de valeurs. Contexte industriel : rechercher le pic de courant relevé par un capteur, ou la mesure la plus élevée d'un lot de pièces contrôlées.
Un technicien qualité dispose d'un tableau de diamètres mesurés (en mm) et souhaite compter combien de pièces sont hors tolérance [mini, maxi].
1. Écris une fonction Python compter_defauts(T, mini, maxi) qui renvoie le nombre de valeurs de T strictement inférieures à mini ou strictement supérieures à maxi.
2. Applique-la au tableau T = [50.02, 49.94, 50.01, 50.07, 49.98, 50.00] avec mini = 49.95 et maxi = 50.05.
1.
def compter_defauts(T, mini, maxi):
compteur = 0
for x in T:
if x < mini or x > maxi:
compteur += 1
return compteur
2. Valeurs testées : 50,02 (conforme) ; 49,94 (< 49,95 → non conforme) ; 50,01 (conforme) ; 50,07 (> 50,05 → non conforme) ; 49,98 (conforme) ; 50,00 (conforme).
compter_defauts(T, 49.95, 50.05) renvoie 2.
Une fonction récursive calcule le cumul de production sur n jours :
def somme_rec(n):
if n <= 0:
return 0
else:
return n + somme_rec(n - 1)
1. Identifie le cas de base et le cas récursif.
2. Déroule le calcul de somme_rec(5) comme dans l'exemple de la factorielle du cours.
3. Donne la complexité de cet algorithme en fonction de n.
1. Cas de base : n <= 0, renvoie 0 sans appel récursif. Cas récursif : n + somme_rec(n - 1), qui ramène le problème à un entier strictement plus petit.
2.
somme_rec(5) = 5 + somme_rec(4)
= 5 + 4 + somme_rec(3)
= 5 + 4 + 3 + somme_rec(2)
= 5 + 4 + 3 + 2 + somme_rec(1)
= 5 + 4 + 3 + 2 + 1 + somme_rec(0)
= 5 + 4 + 3 + 2 + 1 + 0 = 15
3. Il y a exactement n + 1 appels de fonction (un par valeur de 0 à n) : la complexité est \(O(n)\), linéaire.
On reprend la fonction itérative du cours :
def fibonacci(n):
if n == 0:
return 0
a, b = 0, 1
for _ in range(1, n):
a, b = b, a + b
return b
1. Complète le tableau de trace des variables a et b pour l'appel fibonacci(6).
2. Donne la valeur renvoyée.
3. Pourquoi préfère-t-on cette version itérative à la version récursive naïve pour un grand n (par exemple n = 35) ? Rappelle les complexités respectives.
1.
| Étape | a | b |
|---|---|---|
| Initialisation | 0 | 1 |
| _ = 1 | 1 | 1 |
| _ = 2 | 1 | 2 |
| _ = 3 | 2 | 3 |
| _ = 4 | 3 | 5 |
| _ = 5 | 5 | 8 |
2. fibonacci(6) renvoie 8 (on retrouve bien \(F_6 = 8\) dans la suite 0, 1, 1, 2, 3, 5, 8…).
3. La version itérative effectue n itérations : complexité \(O(n)\). La version récursive naïve recalcule un très grand nombre de fois les mêmes valeurs : complexité \(O(2^n)\). Pour n = 35, la récursivité naïve effectue des milliards d'appels contre 35 itérations pour la version itérative — inutilisable en pratique.
Lors du démarrage d'un moteur, la puissance instantanée consommée est modélisée par \(P(t) = t^2\) (\(P\) en W, \(t\) en s) sur l'intervalle \([0\,;\,4]\). On approche l'énergie \(\displaystyle E = \int_0^4 P(t)\,\mathrm{d}t\) par la méthode des rectangles à gauche avec \(n = 4\) sous-intervalles.
1. Calcule le pas h.
2. Complète le tableau de trace (\(k\), \(x_k\), \(P(x_k)\)) et calcule l'approximation de \(E\).
3. La valeur exacte de \(E\) est \(\dfrac{4^3}{3} \approx 21{,}33\). Commente la précision obtenue.
1. \(h = \dfrac{4-0}{4} = 1\,\text{s}\).
2.
| k | \(x_k = k\cdot h\) | \(P(x_k) = x_k^2\) |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 2 | 4 |
| 3 | 3 | 9 |
Somme = \(0+1+4+9 = 14\). \(E \approx h \times 14 = 1 \times 14 = 14\,\text{J}\).
3. L'écart avec la valeur exacte (\(21{,}33 - 14 = 7{,}33\)) est important : la méthode des rectangles à gauche sous-estime fortement l'intégrale d'une fonction croissante, car elle néglige toute la croissance de \(P\) sur chaque sous-intervalle. L'erreur est en \(O(h)\).
On reprend la situation de l'exercice précédent (\(P(t)=t^2\) sur \([0\,;\,4]\), \(n=4\), \(h=1\)), mais avec la méthode des trapèzes.
1. Rappelle la formule des trapèzes puis calcule l'approximation de \(E\).
2. Compare la précision obtenue à celle de la méthode des rectangles (exercice 9) par rapport à la valeur exacte \(21{,}33\).
1. \(E \approx \dfrac{h}{2}\left[P(0) + 2\big(P(1)+P(2)+P(3)\big) + P(4)\right] = \dfrac{1}{2}\big[0 + 2(1+4+9) + 16\big] = \dfrac{1}{2}(0+28+16) = \dfrac{44}{2} = 22\,\text{J}\).
def integrale_trapezes(f, a, b, n):
h = (b - a) / n
somme = f(a) + f(b)
for k in range(1, n):
somme += 2 * f(a + k * h)
return (h / 2) * somme
E = integrale_trapezes(lambda t: t**2, 0, 4, 4)
print(E) # 22.0
2. Rectangles : \(14\) (écart \(7{,}33\)). Trapèzes : \(22\) (écart \(0{,}67\)). La méthode des trapèzes est nettement plus précise pour un même nombre de sous-intervalles, conformément à l'erreur théorique en \(O(h^2)\) contre \(O(h)\) pour les rectangles.
Un bureau d'études cherche la valeur \(x\) telle que \(x^2 = 10\) (dimensionnement d'une section technique), en résolvant \(f(x) = x^2 - 10 = 0\) par la méthode de Newton-Raphson, avec \(x_0 = 3\).
1. Rappelle la formule d'itération de Newton-Raphson et calcule \(f'(x)\).
2. Complète le tableau de trace pour 3 itérations (\(x_n\), \(f(x_n)\), \(x_{n+1}\)).
3. Compare le résultat obtenu à \(\sqrt{10} \approx 3{,}162278\).
1. \(x_{n+1} = x_n - \dfrac{f(x_n)}{f'(x_n)}\) avec \(f'(x) = 2x\).
2.
| \(n\) | \(x_n\) | \(f(x_n)\) | \(f'(x_n)\) | \(x_{n+1}\) |
|---|---|---|---|---|
| 0 | 3,000000 | −1,000000 | 6,000000 | 3,166667 |
| 1 | 3,166667 | 0,027778 | 6,333334 | 3,162281 |
| 2 | 3,162281 | 0,000019 | 6,324562 | 3,162278 |
3. On retrouve \(\sqrt{10} \approx 3{,}162278\) dès la troisième itération : la convergence de Newton-Raphson est très rapide (convergence quadratique — le nombre de décimales exactes double presque à chaque itération).
On cherche \(\sqrt{7}\) en résolvant \(f(x) = x^2 - 7 = 0\) par dichotomie sur l'intervalle \([2\,;\,3]\) (on vérifie \(f(2) = -3 < 0\) et \(f(3) = 2 > 0\)).
1. Complète le tableau de trace pour 3 itérations (\(m\), \(f(m)\), nouvel intervalle).
2. Combien d'itérations faut-il, en partant de \([2\,;\,3]\), pour atteindre une précision \(\varepsilon = 10^{-4}\) ?
1.
| Itération | \(m = \frac{a+b}{2}\) | \(f(m)\) | Signe | Nouvel intervalle |
|---|---|---|---|---|
| 1 | 2,500 | −0,750 | négatif | [2,500 ; 3,000] |
| 2 | 2,750 | 0,5625 | positif | [2,500 ; 2,750] |
| 3 | 2,625 | −0,109375 | négatif | [2,625 ; 2,750] |
On encadre bien \(\sqrt{7} \approx 2{,}645751\) dans \([2{,}625\,;\,2{,}750]\).
2. \(b - a = 1\). \(n \geq \log_2\!\left(\dfrac{1}{10^{-4}}\right) = \log_2(10\,000) \approx 13{,}29\), donc il faut au moins 14 itérations.
Un technicien d'essais relève des tensions (en V) lors d'un contrôle : T = [23, 8, 15, 4, 19]. Trie ce tableau par tri à bulles optimisé (algorithme du cours).
1. Complète le tableau après chaque passage, avec le nombre d'échanges effectués.
2. Combien de passages ont été nécessaires ? Le tableau final est-il trié ?
1.
| Passage | Tableau après passage | Nb échanges |
|---|---|---|
| Initial | [23, 8, 15, 4, 19] | — |
| 1 | [8, 15, 4, 19, 23] | 4 |
| 2 | [8, 4, 15, 19, 23] | 1 |
| 3 | [4, 8, 15, 19, 23] | 1 |
| 4 | [4, 8, 15, 19, 23] | 0 → arrêt |
2. 4 passages ont été effectués (le dernier sans échange déclenche l'arrêt anticipé). Le tableau final [4, 8, 15, 19, 23] est bien trié par ordre croissant.
Un technicien mesure des résistances (en Ω) : T = [34, 12, 47, 9, 22]. Trie ce tableau par sélection (algorithme du cours).
1. Pour chaque valeur de i, indique l'indice du minimum trouvé dans la partie non triée, et le tableau après l'échange éventuel.
2. Le tableau final est-il identique à celui obtenu par un tri à bulles sur les mêmes données ? Justifie sans le recalculer.
1.
| i | Minimum trouvé (indice) | Tableau après l'étape |
|---|---|---|
| 0 | 9 (indice 3) | [9, 12, 47, 34, 22] |
| 1 | 12 (indice 1, déjà en place) | [9, 12, 47, 34, 22] |
| 2 | 22 (indice 4) | [9, 12, 22, 34, 47] |
| 3 | 34 (indice 3, déjà en place) | [9, 12, 22, 34, 47] |
2. Oui : quel que soit l'algorithme de tri utilisé, le résultat final est le même tableau trié par ordre croissant [9, 12, 22, 34, 47] — seul le nombre d'opérations et la façon de parvenir au résultat diffèrent (c'est tout l'intérêt de comparer les complexités).
Un lot de 1000 pièces est référencé par numéro de série. Un technicien informatique compare deux méthodes de recherche d'une pièce défectueuse : une recherche séquentielle (on parcourt le tableau élément par élément) et une recherche dichotomique (le tableau est trié, on divise l'intervalle par deux à chaque étape).
1. Quelle est la complexité de chacune des deux méthodes, en fonction de \(n\), le nombre de pièces ?
2. Pour \(n = 1000\), donne le nombre maximal de comparaisons pour chaque méthode.
3. Quelle condition la recherche dichotomique impose-t-elle sur les données, que la recherche séquentielle n'impose pas ?
1. Recherche séquentielle : \(O(n)\). Recherche dichotomique : \(O(\log_2 n)\).
2. Séquentielle : jusqu'à 1000 comparaisons (pire cas). Dichotomique : \(\log_2(1000) \approx 9{,}97\), donc au plus 10 comparaisons.
3. La recherche dichotomique exige que le tableau soit préalablement trié par numéro de série ; la recherche séquentielle fonctionne sur un tableau quelconque, trié ou non.
Le graphique ci-dessous représente le nombre d'opérations effectuées par quatre algorithmes en fonction de la taille \(n\) des données (\(n\) de 1 à 12).
1. Pour \(n = 10\), quel algorithme effectue le plus d'opérations ? Le moins ?
2. D'après le graphique, à partir de quelle valeur de \(n\) l'algorithme en \(O(n^2)\) dépasse-t-il 50 opérations ?
3. Range les quatre complexités par ordre croissant.
1. Pour \(n=10\) : le plus grand nombre d'opérations est donné par \(O(n^2) = 100\) ; le plus petit par \(O(\log n) \approx 3{,}32\).
2. \(n^2 > 50\) dès que \(n \geq 8\) (\(7^2 = 49 < 50\), \(8^2 = 64 > 50\)).
3. \(O(\log n) \ll O(n) \ll O(n\log n) \ll O(n^2)\).
Un stagiaire a écrit la fonction Python suivante pour calculer la moyenne d'un tableau de mesures, mais elle renvoie un résultat faux :
def moyenne(T):
n = len(T)
somme = 0
for i in range(1, n):
somme = somme + T[i]
return somme / n
Pour T = [10, 20, 30, 40], cette fonction renvoie 22,5 au lieu de 25.
1. Trace l'exécution de moyenne([10, 20, 30, 40]) et explique l'origine de l'erreur.
2. Corrige le programme.
1. La boucle for i in range(1, n) parcourt i = 1, 2, 3 : elle ne prend jamais en compte T[0] = 10. La somme calculée est \(20+30+40 = 90\), et \(90 / 4 = 22{,}5\) au lieu de \(\dfrac{10+20+30+40}{4} = 25\). L'erreur est un indice de départ mal choisi (indexation hors domaine utile).
2.
def moyenne(T):
n = len(T)
somme = 0
for i in range(n): # correction : range(0, n)
somme = somme + T[i]
return somme / n
print(moyenne([10, 20, 30, 40])) # affiche 25.0
Une étuve industrielle doit atteindre une consigne de 80 °C. Le régulateur PID numérique du cours utilise \(K_p = 1{,}0\), \(K_i = 0{,}2\), \(K_d = 0\) (terme dérivé négligé ici) et une période d'échantillonnage \(T_e = 1\,\text{s}\). Les trois premières mesures relevées par le capteur sont : 60 °C, 68 °C, 74 °C.
1. Rappelle la formule de la commande \(u_k\) du cours (avec \(K_d = 0\)).
2. Complète le tableau de trace pour \(k = 0, 1, 2\) : erreur \(e_k\), somme cumulée, commande \(u_k\).
3. Comment évolue la commande \(u_k\) au fil des itérations ? Explique pourquoi, en lien avec l'évolution de l'erreur.
1. \(u_k = K_p\,e_k + K_i\,T_e\displaystyle\sum_{j=0}^{k} e_j\) (le terme dérivé est nul ici).
2.
| k | mesure | \(e_k =\) consigne − mesure | somme cumulée \(\sum e_j \cdot T_e\) | \(u_k\) |
|---|---|---|---|---|
| 0 | 60 | 20 | 20,0 | 1×20 + 0,2×20,0 = 24,0 |
| 1 | 68 | 12 | 32,0 | 1×12 + 0,2×32,0 = 18,4 |
| 2 | 74 | 6 | 38,0 | 1×6 + 0,2×38,0 = 13,6 |
3. La commande \(u_k\) diminue progressivement (24,0 → 18,4 → 13,6) car l'erreur \(e_k\) diminue à mesure que la température de l'étuve se rapproche de la consigne : le terme proportionnel Kp*e baisse plus vite que le terme intégral Ki*somme_e n'augmente. C'est le comportement attendu d'une régulation qui converge vers la consigne.