Processing math: 100%

La programmation, c’est comme l’amour : il y a plusieurs façons de pratiquer! Et aujourd’hui, j’avais envie d’explorer différentes façons de calculer la somme:Sn=12+22++n2=nk=1k2.

Méthode 1 : méthode mathématique

C’est la plus économe en terme de mémoire : la complexité en mémoire et en temps est imbattable. Il suffit d’utiliser la formule mathématique:Sn=n(n+1)(2n+1)6que l’on peut démontrer par récurrence (mais ce n’est pas l’objectif de cet article). On trouve alors pour n = 20 par exemple: S20=20×21×416=2870.Le programme Python est alors le suivant:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
n = 20
print ( int( n * (n + 1) * (2*n + 1) / 6 ) )
n = 20 print ( int( n * (n + 1) * (2*n + 1) / 6 ) )
n = 20
print ( int( n * (n + 1) * (2*n + 1) / 6 ) )

Méthode 2 : calcul bourrin

Quand on n’est pas trop au fait des formules mathématiques (oui, oui ! vous avez le droit !), on peut faire un calcul itératif « bourrin ». Cela donne alors:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
S, n = 0, 20
for k in range(1,n+1):
S += k ** 2
print(S)
S, n = 0, 20 for k in range(1,n+1): S += k ** 2 print(S)
S, n = 0, 20

for k in range(1,n+1):
    S += k ** 2

print(S)

La complexité en mémoire est ici en O(n).

Méthode 3 : programmation fonctionnelle

On peut utiliser la fonction reduce() du module functools. Elle fait partie des outils de la programmation fonctionnelle que l’on voit en Spécialité NSI en Terminale, dès la rentrée 2020.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from functools import reduce
liste = [ k ** 2 for k in range(1,21) ]
print ( reduce(lambda a, x: a + x, liste) )
from functools import reduce liste = [ k ** 2 for k in range(1,21) ] print ( reduce(lambda a, x: a + x, liste) )
from functools import reduce
liste = [ k ** 2 for k in range(1,21) ]
print ( reduce(lambda a, x: a + x, liste) )

On construit d’abord une liste des valeurs à sommer, puis on affiche le résultat de la fonction reduce(), celle-ci admettant comme arguments une fonction à 2 arguments (ici, lambda, qui ajoute toutes les valeurs de la liste) ainsi qu’une liste.

Le principe de la fonction reduce() est celui-ci dans notre exemple : on parcourt la liste et on calcule la somme de l’élément sur lequel on est et de l’antécédent (a), qui est le résultat de la somme trouvé précédemment. Le problème avec cette « mécanique », c’est que le premier élément n’admet pas d’antécédent. Ainsi, la fonction reduce() assimile le premier élément à l’antécédent du deuxième… ce qui peut être problématique. Il faut donc créer une liste contenant directement les élements à ajouter (pour notre exemple).

Ainsi, le code suivant:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from functools import reduce
print ( reduce(lambda a, x: a + x ** 2 , range(1,21)) )
from functools import reduce print ( reduce(lambda a, x: a + x ** 2 , range(1,21)) )
from functools import reduce

print ( reduce(lambda a, x: a + x ** 2 , range(1,21)) )

fonctionne correctement car 1² = 1 (que la fonction confonde 1 et 1² ne change donc pas le résultat), mais si on souhaite calculer:22+32++202 le code suivant:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
from functools import reduce
print ( reduce(lambda a, x: a + x ** 2 , range(2,21)) )
from functools import reduce print ( reduce(lambda a, x: a + x ** 2 , range(2,21)) )
from functools import reduce

print ( reduce(lambda a, x: a + x ** 2 , range(2,21)) )

affiche « 2867 » et non « 2869 » comme attendu. En effet, ce dernier code calcule: 2+32+42++202.

Méthode 4 : récursivité

La récursivité consiste à définir une fonction dans laquelle on fait appel à cette fonction. Cela donne pour notre exemple:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def somme(n):
if n == 1:
return 1
return n ** 2 + somme( n - 1 )
print( somme(20) )
def somme(n): if n == 1: return 1 return n ** 2 + somme( n - 1 ) print( somme(20) )
def somme(n):
    if n == 1:
        return 1

    return n ** 2 + somme( n - 1 )

print( somme(20) )

Méthode 5 : diviser pour régner

Cette méthode consiste à subdiviser un problème en sous-problèmes plus faciles à traiter en utilisant la récursivité.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
def somme(L):
if len(L) == 1:
return L[0]
else:
L1 = L[:len(L)//2]
L2 = L[len(L)//2::]
return somme(L1) + somme(L2)
print( somme( [k ** 2 for k in range(1,21) ] ) )
def somme(L): if len(L) == 1: return L[0] else: L1 = L[:len(L)//2] L2 = L[len(L)//2::] return somme(L1) + somme(L2) print( somme( [k ** 2 for k in range(1,21) ] ) )
def somme(L):
    if len(L) == 1:
        return L[0]
    else:
        L1 = L[:len(L)//2]
        L2 = L[len(L)//2::]
        return somme(L1) + somme(L2)

print( somme( [k ** 2 for k in range(1,21) ] ) )

L’idée est ici de découper la liste en 2 sous-listes L1 et L2, et de faire appel à la fonction somme() jusqu’à ce que la liste passée en argument ne contienne qu’un seul élément.


0 0 votes
Évaluation de l'article
S’abonner
Notification pour
guest


1 Commentaire
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
Nicolas Patrois

Une variante de la méthode fonctionnelle, sans reduce :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
somme=lambda n:sum(i*i for i in range(1,n+1)
somme=lambda n:sum(i*i for i in range(1,n+1)
somme=lambda n:sum(i*i for i in range(1,n+1)

Ou si on aime map et lambda :

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
carré=lambda n:n*n
somme=lambda n:sum(map(carré,range(1,n+1)))
carré=lambda n:n*n somme=lambda n:sum(map(carré,range(1,n+1)))
carré=lambda n:n*n
somme=lambda n:sum(map(carré,range(1,n+1)))
0
    0
    Votre panier
    Votre panier est vide
    1
    0
    Nous aimerions avoir votre avis, veuillez laisser un commentaire.x