En raison de la pandémie Covid-19, les E3C du mois de Mai ont été annulés, notamment en mathématiques. La Banque Nationale de Sujets a publié, le 15 Mai dernier, 65 sujets en mathématiques. Ces sujets contiennent, conformément au programme, des questions sur des algorithmes, cet article s’y intéresse.
Cet article peut être librement diffusé et son contenu réutilisé pour une utilisation non commerciale (contacter l’auteur pour une utilisation commerciale) suivant la licence CC-by-nc-sa
Dans le programme de mathématiques de première générale (spécialité Mathematiques) on trouve parmi la liste des compétences mathématiques travaillées :
– Calculer, appliquer des techniques et mettre en œuvre des algorithmes ;
Ainsi, il y a dans ce programme des indications au sujet de ces algorithmes que l’on peut mettre en œuvre, ils sont illustrés dans cet article et l’on pouvait s’attendre à les retrouver dans les sujets de LA BANQUE NATIONALE DE SUJETS .
On y trouve 65 sujets, parmi lesquels 7 ne présentent pas d’algorithmes, 2 en proposent deux et donc 56 en proposent un.
On peut déplorer les choix éditoriaux concernant l’écriture de ces sujets, l’utilisation de Word et de polices inadaptées conduisent à de grandes disparités quand à la qualité d’écriture des algorithmes, il y a là matière à améliorer les choses de façon à présenter un peu plus sérieusement les sujets aux collègues et aux élèves.
Autant le programme est riche en contenu algorithmique, autant ces sujets sont restés proche du niveau 0, nous allons en faire le tour.
Commençons par le sujet 1, celui que tout le monde va ouvrir en allant consulter cette BNS. Il contient bien un algorithme dans l’exercice 3 :
Lors du lancement d’un hebdomadaire, 1200 exemplaires ont été vendus.
Une étude de marché prévoit une progression des ventes de 2% chaque semaine.
On modélise le nombre d’hebdomadaires vendus par une suite $(𝑢_𝑛)$ où $𝑢_𝑛$ représente le nombre de journaux vendus durant la 𝑛-ième semaine après le début de l’opération. On a donc $𝑢_0 = 1200$.
1) Calculer le nombre $𝑢_2$. Interpréter ce résultat dans le contexte de l’exercice.
2) Écrire, pour tout entier naturel $𝑛$, l’expression de $𝑢_𝑛$ en fonction de $𝑛$.
3) Voici un programme rédigé en langage Python :
def suite():
u=1200
S=1200
n= 0
while a<30000:
n=n+1
u=u*1.02
S=S+u
return(n)
Le programme retourne la valeur 30. Interpréter ce résultat dans le contexte de l’exercice.
4) Déterminer le nombre total d’hebdomadaires vendus au bout d’un an.
Faisons fonctionner ce programme :
- >>> suite()
- Traceback (most recent call last):
- File "<pyshell#116>", line 1, in <module>
- suite()
- File "/home/clerc/Documents/maths/spe1ere/E3C/E3C_1.py", line 5, in suite
- while a<30000:
- NameError: name 'a' is not defined
Mince ! Bon, il s’agit peut-être d’une erreur de recopie du programme, changeons la ligne while a<30000:
par while S<30000:
Faisons fonctionner ce programme :
- >>> suite()
- 20
C’est mieux mais ça ne correspond pas à l’énoncé ...
Voici l’algorithme qui convient pour cet énoncé :
- def suite():
- u=1200
- S=1200
- n= 0
- while S<50000:
- n=n+1
- u=u*1.02
- S=S+u
- return(n)
- >>> suite()
- 30
On notera que le programme, même s’il contenait des erreurs, était bien écrit et il était annoncé qu’il s’agissait d’un programme écrit en Python, par contre il n’y avait pas la coloration syntaxique.
Cet algorithme est un algorithme de seuil, la star des sujets de la BNS, on le retrouvera dans des dizaines de sujets.
Il est quand même assez inquiétant de voir ça dans le sujet 1 de la BNS ...
L’algorithme proposé dans le sujet 2 est encore un algorithme de seuil, il est écrit en pseudo-code en respectant les préconisations de l’Inspection Générale en matière d’écriture des algorithmes :
U←0,2
S←0,2
N←0
Tant que ............................
U←..........
S←..........
N←N+1
Fin tant que
Afficher N
Par contre cet algorithme n’est pas dans l’air du temps avec initialisation des variables, affichage ... C’est un algorithme à compléter, on en trouvera beaucoup dans la BNS.
Dans le sujet 3, l’algorithme est l’objet d’une question du QCM, cela se retrouvera plusieurs fois dans la BNS :
Question 5
On considère la fonction Python suivante :
def evolu(k):
i=200
n=0
while i<k:
i=1.2*i+10
n=n+1
return n
evolu(500)=4 | evolu(600)=5 | evolu(300)=3 | evolu(400)=4 |
Le programme est correct et renvoie :
- >>> evolu(300)
- 2
- >>> evolu(400)
- 4
- >>> evolu(500)
- 5
- >>> evolu(600)
- 6
On est là clairement dans les attendus du programme avec une écriture de l’algorithme selon les préconisations officielles.
Dans le sujet 4, l’algorithme utilise les listes qui sont au programme :
- def Jeu(L,G):
- n=len(L)
- E=0
- for i in range(n):
- E=E+L[i]*G[i]
- return(E)
L’algorithme est proposé avec coloration syntaxique, petit problème l’énoncé est le suivant :
Que retourne la fonction Jeu écrite ci-dessous en langage Python avec les listes : L=[-5 ;5 ;25] et G=[0,5625 ;0,375 ;0,0625] ?
- >>> L=[-5;5;25]
- SyntaxError: invalid syntax
- >>> G=[0,5625;0,375;0,0625]
- SyntaxError: invalid syntax
- >>> Jeu([-5;5;25],[0,5625;0,375;0,0625])
- SyntaxError: invalid syntax
L’énoncé correct est :
Que retourne la fonction Jeu écrite ci-dessous en langage Python avec les listes : L=[-5,5,25] et G=[0.5625,0.375,0.0625] ?
Ce qui n’est pas du tout pareil, et les élèves le savent ...
- >>> Jeu([-5,5,25],[0.5625,0.375,0.0625])
- 0.625
Dans le sujet 5, il s’agit encore d’un algorithme de seuil mais cette fois-ci le seuil est un paramètre d’une fonction à compléter :
Def seuil(a) :
n = 0
while (n+2) / (n+1) ...a :
n = ...
return ...
Cet algorithme ne peut pas fonctionner :
– Def au lieu de def : Erreur à la compilation
– n = ... : Erreur d’indentation après le while
– return ... : Erreur d’indentation, le return est hors de la fonction
Après correction :
- def seuil(a):
- n = 0
- while (n+2)/(n+1)>a:
- n =n+1
- return n
RAS.
Dans le sujet 6, il s’agit de calculer la somme des termes d’une suite en complétant un programme écrit en Python :
def Suite():
U=400
S=0
for i in range(20):
S=..........
U=..........
return(...)
Cet algorithme ne peut pas fonctionner, le return
est en dehors de la fonction.
Même si cela n’est pas une erreur, il est étonnant de voir le return
suivi de parenthèses, cela peut prêter à confusion et laisser à penser qu’il faut renvoyer un tuple ...
Voici le programme correct complété :
- def Suite():
- U=400
- S=0
- for i in range(20):
- S=S+U
- U=0.9*U+60
- return S
Ce qui peut paraître déroutant pour les élèves c’est que la fonction calcule $S_i$ et $u_{i+1}$ à chaque boucle mais l’algorithme doit permettre de calculer la somme S des 20 premiers termes de la suite $u_n$, ce qu’il fait.
Dans le sujet 7, un autre type de seuil est calculé puisque l’algorithme renvoie la valeur de n pour laquelle $u_n > v_n$ pour la première fois :
def algo():
n=0
u=-4
v=0
while u<v:
n=n+1
u=(8*n-4)/(n+1)
v=0.5*v+3.5
return(n)
Ici, il est demandé à l’élève, à qui on a indiqué que l’algorithme renvoyait la valeur 11, d’expliquer ce que fait ce programme.
Dans le sujet 8, utilisation d’une liste et de booléens un peu surprenante :
- liste=[0,0,0,0,0,0,0]
- for x in range(0,7):
- if x**3-12*x**2+36*x>=5:
- liste[x]=1
- print(liste)
Pour chaque indice de la liste, la valeur initiale est 0, on fait un test et on met la valeur à 1 si le test est positif, on obtient :
[0, 1, 1, 1, 1, 1, 0]
Dans le sujet 9, nous trouvons une recherche de racines d’une équation par dichotomie, c’est le seul sujet qui propose cela :
- def zero_de_f(n):
- a=1
- b=2
- for k in range(n):
- x=(a+b)/2
- if x**3-x**2-x-1<0:
- a=x
- else:
- b=x
- return a,b
on demande à l’élève de compléter ce tableau :
Itération | $𝒙=\frac{𝒂+𝒃}{𝟐}$ | $𝒇(𝒙) < 0$ ? | $a$ | $b$ | Amplitude de [𝒂 ;𝒃] |
𝑘=0 | 1,5 | 𝑂𝑈𝐼 | 1,5 | 2 | 0,5 |
𝑘=1 | |||||
𝑘=2 |
Utilisation du programme :
- >>> zero_de_f(3)
- (1.75, 1.875)
Dans le sujet 10, il y a deux algorithmes !!!
Le premier est dans le QCM, il est écrit en langage usuel :
Suite(N)
A ← 10
Pour k de 1 à N
A ← 2*A-4
FinPour
Renvoyer A :
Pour la valeur N = 4 le résultat affiché sera :
a) 4 | b) 100 | c) 52 | d) 196 |
- def Suite(N):
- A=10
- for k in range(1,N):
- A=2*A-4
- return A
Là il y a une difficulté parce que Python renvoie :
- >>> Suite(4)
- 52
Alors qu’il y a fort à parier que l’auteur attende la réponse 100 ...
En effet en langage naturel on doit boucler de 1 à 4 (On verra cela dans un autre sujet), 4 compris, alors que dans Python for k in range(1,4):
boucle de 1 à 4 non compris, donc de 1 à 3 en fait ...
Le second algorithme est un algorithme de seuil classique :
- def seuil():
- u=120000
- n=0
- while u<400000:
- n=n+1
- u=1.02*u
- return n
Mais voici ce qui est demandé à l’élève :
« Déterminer la valeur affichée par cet algorithme et interpréter le résultat précédent dans le contexte de l’exercice »
Or si on utilise l’algorithme :
- >>> seuil()
- 61
Il n’est pas raisonnable de demander à un élève de faire cela à la main, cela signifie donc que l’on attend de lui qu’il programme cela sur sa calculatrice ...
Or avec les nouveaux programmes, je ne crois pas que les enseignants continuent à apprendre la programmation des calculatrices en langage constructeur (moi je ne le fais plus en tout cas ...), il faut donc que les élèves disposent de calculatrices qui émulent Python. Pas un de mes élèves n’en disposait cette année ...
Encore un algorithme de seuil dans le sujet 11 : RAS.
Pas d’algorithmes dans les sujets 12 et 13.
Dans le sujet 14, à nouveau un seuil avec demande de la valeur renvoyée, ici c’est 15, c’est un peu plus raisonnable et l’élève peut obtenir cette valeur en saisissant sur sa calculatrice :
1000
0.82*Rep+3.6
Puis il appuie sur « enter » autant de fois que nécessaire pour être en-dessous de 70 (Il faut qu’il compte combien de fois il appuie sur « enter »).
- def froid():
- T=1000
- n=0
- while T>70:
- T=0.82*T+3.6
- n=n+1
- return n
- >>> froid()
- 15
Dans le sujet 15, l’algorithme est une question du QCM :
La donne réponse est la C) mais elle est mal écrite, tel quel l’algorithme ne fonctionne pas puisqu’il faut écrire :
- u=4
- for k in range(5):
- u=3*u-5
Dans le sujet 16, un algorithme de seuil : RAS.
Dans le sujet 17, une question de QCM et encore un dilemme :
Sur ma calculatrice , le programme est le suivant :
-2->U
-2->S
For(I,1,36)
2*U-5->U
S+U->S
End
Ce qui correspond à la réponse d).
En Python, c’est celui-ci :
- U=-2
- S=-2
- for i in range(1,37):
- U=2*U-5
- S=S+U
Ce qui n’est pas proposé ... Alors ? On répond quoi ???
Il n’y a pas d’algorithme dans le sujet 18, peut-être parce qu’il y a une question tableur ...
Dans le sujet 19, algorithme de seuil : RAS.
Dans le sujet 20, calcul d’une somme de termes : RAS.
Dans le sujet 21, si l’élève suit l’énoncé il est obligé de programmer un algorithme de seuil pour une fonction :
- from math import exp
- def f(t):
- return 1375*exp(-0.075*t)+25
- def seuil():
- t=0
- temperature=1400
- while temperature >=600:
- t=t+0.1
- temperature=f(t)
- return t
On peut toujours répondre à cette question en utilisant une fonction dans la calculatrice et son tableau de valeurs (par exemple), sinon il y a 117 itérations pour le programme :
- >>> seuil()
- 11.7
Dans le sujet 22, l’algorithme proposé ne répond pas à la question posée :
- def annee():
- d=537
- n=0
- while d>513:
- n=n+1
- d=d*(1-1.5/100)
- return n
En effet il renvoie :
- >>> annee()
- 4
Ce qui n’est pas l’année mais le nombre d’années ...
Pour corriger cela il suffit d’initialiser $n$ autrement : n=2019
Dans le sujet 23, question de QCM : RAS.
Dans le sujet 24, un algorithme de seuil avec deux suites . RAS.
Dans le sujet 25, un calcul d’année cette fois ci bien formulé.
Dans le sujet 26, il est demandé d’écrire intégralement une fonction Python, sans aucune indication.
Le programme à produire est quand même assez simple :
- def annee():
- d=400
- n=2018
- while d>365:
- n=n+1
- d=d*(1-1.5/100)
- return n
On a cependant vu précédemment que ce n’est pas toujours clair pour tout le monde ce calcul d’année ...
Dans le sujet 27, algorithme de seuil : RAS.
Dans le sujet 28, algorithme de seuil : RAS.
Dans le sujet 29, algorithme de seuil : RAS.
Dans le sujet 30, problème de syntaxe :
def nombreCompressions(A):
t = 800
n = 0
While t > A :
t = t*0,83
n = n+1
return n
– Il y a une majuscule à While
, le script n’est pas compilé.
– Il y a une virgule à la place d’un point dans 0,83 :
- >>> nombreCompressions(50)
- Traceback (most recent call last):
- File "<pyshell#99>", line 1, in <module>
- nombreCompressions(50)
- File "/home/clerc/Documents/maths/spe1ere/E3C/E3C_30.py", line 4, in nombreCompressions
- while t>A:
- TypeError: '>' not supported between instances of 'tuple' and 'int'
Le bon script :
- def nombreCompressions(A):
- t=800
- n = 0
- while t>A:
- t=t*0.83
- n=n+1
- return n
Dans le sujet 31, algorithme de seuil (Le seuil est en paramètre d’une fonction) : RAS.
Il n’y a pas d’algorithme dans le sujet 32.
Dans le sujet 33, l’algorithme à compléter doit calculer une somme et un seuil, le seuil est donné dans l’énoncé mais pas la somme :
- i = 1
- u = 2
- longueur = 2
- while longueur < 1000:
- i =i+1
- u =u*1.5
- longueur =longueur+u
- print(i)
- 14
- >>> longueur
- 1163.717041015625
Dans le sujet 34, la fonction qui calcule les termes d’une suite est donnée :
- def terme(n):
- w=4
- for i in range(n):
- w=2*w-3
- return w
Puis on demande cela aux élèves : « En s’inspirant de la fonction terme(n)
, proposer une fonction somme_termes(n)
, écrite en langage Python,qui renvoie la somme des $n$ premiers termes de la suite $(w_n)$. »
Soit :
- def somme_termes(n):
- s=0
- for i in range(n):
- s=s+terme(i)
- return s
Attention, on a bien terme(0) qui renvoie 4 et somme_termes(4) qui renvoie $w_0 + w_1 + w_2 + w_3$, c’est-à-dire 27.
- >>> terme(0)
- 4
- >>> somme_termes(4)
- 27
Dans le sujet 35, on demande de compléter la fonction qui calcule le terme de rang $n$ d’une suite : RAS.
Dans le sujet 36, algorithme de seuil : RAS.
Dans le sujet 37, algorithme de seuil (Le seuil est en paramètre d’une fonction) : RAS.
Dans le sujet 38, algorithme de seuil (Le seuil est en paramètre d’une fonction) : RAS.
Dans le sujet 39, algorithme de seuil : RAS.
Dans le sujet 40, algorithme de seuil : RAS.
Dans le sujet 41, on donne la fonction qui calcule le terme de rang $n$ d’une suite : RAS.
Dans le sujet 42, algorithme de seuil : RAS.
Dans le sujet 43, algorithme de seuil avec deux suites : RAS.
Dans le sujet 44, c’est n’importe quoi ... Dans nombre de sujets précédents il y a des problèmes avec les images et/ou avec les formules mathématiques, dans celui-ci c’est la catastrophe. Contient un algorithme de seuil : RAS.
Dans le sujet 45, l’algorithme est l’objet d’une question du QCM :
La fonction liste(N) calcule les N premiers termes de la suite de premier terme 1 définie par récurrence par $u_{n+1} = 2u_n + 3$ :
- def liste(N):
- U=1
- L=[U]
- for i in range(1,N):
- U=2*U+3
- L.append(U)
- return(L)
D’où la réponse au QCM :
- >>> liste(4)
- [1, 5, 13, 29]
Dans le sujet 46, algorithme de seuil avec deux suites : RAS.
Dans le sujet 47, algorithme de seuil : RAS.
Dans le sujet 48, algorithme de seuil : RAS.
Dans le sujet 49, on demande dans un QCM de choisir la fonction qui calcule le terme de rang $n$ d’une suite : RAS.
Dans le sujet 50, on donne la fonction qui calcule le terme de rang $n$ d’une suite : RAS.
Dans le sujet 51, un algorithme de seuil est donné :
- def seuil():
- t=0
- puissance=120
- while puissance<=60:
- t=t+0.1
- puissance=120*exp(-0,14*t)
- return t
Or cet algorithme contient deux grosses erreurs et il renvoie 0, en effet la boucle n’est pas démarrée puisque puissance = 120 > 60, on corrige cela en écrivant while puissance>=60:
, on a une nouvelle erreur parce que la fonction exp n’est pas nativement dans Python, il faut l’importer from math import exp
, on a alors une nouvelle erreur :
- >>> seuil()
- Traceback (most recent call last):
- File "<pyshell#64>", line 1, in <module>
- seuil()
- File "/home/clerc/Documents/maths/spe1ere/E3C/E3C_51.py", line 7, in seuil
- puissance=120*exp(-0,14*t)
- TypeError: exp() takes exactly one argument (2 given)
En effet, le séparateur de la partie entière et de la partie décimale est le « . » et pas la « , », d’où l’algorithme suivant :
- from math import exp
- def seuil():
- t=0
- puissance=120
- while puissance>=60:
- t=t+0.1
- puissance=120*exp(-0.14*t)
- return t
Voici ce que l’on obtient en sortie :
- >>> seuil()
- 4.999999999999998
On peut bien sûr répondre à cette question sans programmer en utilisant le tableau de valeurs de la fonction sur calculatrice ...
Dans le sujet 52, l’algorithme qui calcule la somme des n premiers termes d’une suite géométrique est donné :
- def somme(A):
- S=0
- n=0
- while n<=A:
- S=S+7800*1.0152**n
- n = n + 1
- return S
Sont également donnés les résultats suivants :
- >>> somme(0)
- 7800.0
- >>> somme(1)
- 15718.560000000001
- >>> somme(2)
- 23757.482112000005
- >>> somme(3)
- 31918.595840102407
- >>> somme(8)
- 74623.04180934158
Ce qui permet de répondre aux questions sans programmer la fonction. À noter que la somme est faite grâce à une boucle while
là où on attendrait plutôt une boucle for
:
- def somme2(A):
- S=0
- n=0
- for i in range(A+1):
- S=S+7800*1.0152**i
- return S
Dans le sujet 53, on demande de compléter la fonction qui calcule le terme de rang $n$ d’une suite : RAS.
Dans le sujet 54 et le sujet 55, on donne la fonction qui calcule le terme de rang $n$ d’une suite : RAS.
Dans le sujet 56, un algorithme de seuil est à compléter : RAS.
Dans le sujet 57, il n’y a pas d’algorithme.
Dans le sujet 58, l’élève doit reproduire et compléter un algorithme qui permet de déterminer au bout de combien d’années la population d’une ville A dépasse celle d’une ville B, la fonction est malheureusement appelée année ...
- def annee():
- u=4600
- v=5100
- n=0
- while u<v:
- u=1.02*u
- v=v+110
- n=n+1
- return n
Dans le sujet 59, l’algorithme est l’objet d’une question du QCM :
La bonne réponse est :
- def Somme():
- s=0
- for k in range(101):
- s=s+k
- return s
Ce qui est la somme des entiers de 0 à 100, pas de 1 à 100 comme dit dans l’énoncé ...
Dans les sujets 60 et 61, il n’y a pas d’algorithme, cependant dans le sujet 61 il y a cette question dans l’exercice 2 :
2.Déterminer le nombre minimal 𝑁 de rebonds à partir duquel la hauteur atteinte par la balle est inférieure à 20 cm. Expliquer la démarche employée.
Question à laquelle on peut répondre à l’aide d’un algorithme de seuil :
- h=2
- N=0
- while h>0.2:
- h=0.8*h
- N+=1
- print(N)
Dans le sujet 62, on donne la fonction qui calcule le terme de rang $n$ d’une suite : RAS.
Dans le sujet 63, un algorithme de seuil est à compléter : RAS.
Dans le sujet 64, voici l’algorithme donné aux élèves :
def nb_jours:
j=1
u=50
S=50
While......:
u=0,98*u
S=S+u
j=......
return j
– Le nom de la fonction n’est pas suivi de (), l’algorithme ne peut pas fonctionner ;
– Le While est écrit avec une majuscule, l’algorithme ne peut pas fonctionner ;
– 0,98 est écrit avec une virgule, l’algorithme ne peut pas fonctionner.
Voici ce que l’on doit avoir :
- def nb_jours():
- j=1
- u=50
- S=50
- while S<2000:
- u=0.98*u
- S=S+u
- j=j+1
- return j
Dans le sujet 65, algorithme de seuil avec deux suites : RAS.
En conclusion, on peut être indulgent pour une première année de réforme, mais cela montre plusieurs choses à prendre en compte :
– Il faudrait uniformiser les énoncés, les captures d’écran devraient être proscrites ou alors réalisée avec soin ;
– Il faudrait clarifier le vocabulaire : fonction, programme, algorithme
– Il faudrait clarifier les attendus en algorithmique (exécuter, écrire, corriger, compléter) et les connaissances (savoir que exp est dans la bibliothèque math, range(n), range(a,b) ou range (a,b,s))