Accumulateur et while☘
Exercice☘
Écrire une fonction python prenant en entrée un entier naturel M et renvoyant en sortie le plus grand entier naturel n tel que 0+1+2+\dots+n \leqslant M.
>>> fin_auplus(2)
1
>>> fin_auplus(3)
2
>>> fin_auplus(4)
2
>>> fin_auplus(5)
2
>>> fin_auplus(6)
3
>>> fin_auplus(9)
3
>>> fin_auplus(10)
4
Le principe
Dans une variable S (initialisée à 0), on va accumuler les entiers successifs jusqu'à dépasser la valeur M donnée au préalable.
Par exemple, si l'on s'est donné au départ la valeur M=11:
S ← 0
S ← S + 1 # S a pour valeur 1, S <= 11: on continue
S ← S + 2 # S a pour valeur 3, S <= 11: on continue
S ← S + 3 # S a pour valeur 6, S <= 11: on continue
S ← S + 4 # S a pour valeur 10, S <= 11: on continue
S ← S + 5 # S a pour valeur 15, S > 11: on stoppe
La dernière valeur pour laquelle on a encore S <= 11 est la valeur 4:
0+1+2+3+4 \leqslant 11 mais 0+1+2+3+4+5 >11.
Notre fonction doit donc renvoyer 4.
On doit essentiellement répéter une action (du type S ← S + un entier
)
tant qu'une condition reste vraie (ici S <= M
).
Cela se traduit bien sûr par une boucle while.
pseudo-code
fonction fin_auplus(M):
i ← 0 # i va parcourir les valeurs 0, 1, 2, 3, ...
S ← 0 # S servira d'accumulateur: on y ajoutera une à une les valeurs de i
Tant que S <= M:
i ← i+1
S ← S + i
renvoyer i-1
Remarquez qu'on renvoie i-1
car la dernière valeur prise par i est celle
qui fait "déborder", c'est la valeur qui fait que la condition du while
devient fausse (qui fait que l'on a S > M), or nous voulons la dernière valeur
pour laquelle la condition est encore vraie.
code python
def fin_auplus(M):
"""
M -- entier naturel
renvoie le plus grand entier n tel que
0+1+2+...+n <= M
"""
i = 0
S = 0
while S <= M:
i += 1
S += i
return i-1
Exercice☘
On reprend l'exercice de la page précédente:
Écrire une fonction prenant en entrée un entier naturel A non nul et renvoyant le plus petit entier m tel que 2^m > A.
Mais il s'agit maintenant d'écrire une version dans laquelle on s'interdira d'utiliser ** pour calculer une puissance.
Indication: accumulateur
L'idée, pour calculer les puissances de 2 successives sans utiliser **, est à nouveau celle de l'accumulateur.
Le nombre 2^n est le produit de
2, 2, 2, ..., 2:
2n = 2×2×2×...×2 peut se calculer en "accumulant" les facteurs 2...
On commence par:
P ← 1
Puis on multiplie par 2 à chaque étape le contenu de P:
P ← 2P # P désigne maintenant la valeur 2
P ← 2P # P désigne maintenant la valeur 2 × 2 = 22
P ← 2P # P désigne maintenant la valeur 2 × 22 = 23
P ← 2P # P désigne maintenant la valeur 2 × 23 = 24
P ← 2P # P désigne maintenant la valeur 2 × 24 = 25
....
Un code python
def depasseA(A):
"""
A -- entier naturel non nul
renvoie le plus petit entier n tel que 2**n > A
"""
n = 0
p = 1 # on a p = 1 = 2^0 = 2^n
while p <= A:
n += 1
p = 2*p # p = 2^n à chaque fin de passage dans la boucle
return n
Remarque: cette fois, on renvoie n et non n-1 car on veut le premier entier qui rend la condition fausse (dans l'exercice précédent, on voulait le dernier entier laissant la condition vraie).