Elixir: calculer la somme des n premiers entiers
Pour illustrer la programmation récursive avec Elixir et montrer quelques aspects sympathiques du langage, j’ai choisi un classique et très simple problème mathématique: calculer la somme des n premiers entiers. Par exemple:
Somme des n premiers entiers si n vaut 5
5 + 4 + 3 + 2 + 1 = 15
Super simple. C’est comme la factorielle mais avec des additions. Pas de quoi choper des boutons, même si on déteste les maths. C’est un bon problème pour illustrer les fonctions récursives. En programmation procédurale on ferait quelque chose dans ce genre là:
somme = 0
for(i = n; i > 0; i--) {
somme += n
}
Ma première tentative avec Elixir donne le programme suivant:
Vous le lancez comme ça:
$ elixir somme.exs
15
Sachez dès maintenant que ce bout de code n’est pas dans l’esprit Elixir. J’ai cherché à décomposer toutes les étapes, pas à faire quelque chose de beau, ou d’optimisé, ou de compact. Alors, que fais ce programme ?
C’est la définition d’une méthode run
. Le paramètre acc
est le diminutif de
accumulator. Avoir un accumulateur est un truc très utilisé dans ce type de
fonction. On enregistre le résultat provisioire dans cet accumulateur, qui
est propagé tout au long de la pile d’appels.
Ici je calcule deux résultats temporaires. Dans somme
je place la somme du
nombre n actuel et de l’accumulateur. Quant à suivant
, il contient la
prochaine valeur du nombre n.
Dans une fonction récursive il faut évidemment un appel à cette même fonction.
Mais surtout il faut une
condition de sortie. Sans ce garde-fou, c’est la boucle infinie à tout les
coups. Ici la condition de sortie est suivant == 0
. Quand le prochain nombre
à traiter atteint zéro, c’est le signe que la fonction a terminé son travail donc
je renvois le résultat actuel, qui est la somme de tous les nombres traités
jusqu’ici. Dans l’autre cas, c’est l’appel récursif: run(suivant, somme)
.
Si vous avez du mal à comprendre la logique de ce programme, vous pouvez ajouter un traçage:
Ce qui donnera le résultat suivant:
$ elixir somme.exs
n: 5 --- acc: 0
n: 4 --- acc: 5
n: 3 --- acc: 9
n: 2 --- acc: 12
n: 1 --- acc: 14
15
La prochaine fois je transformerais ce programme afin qu’il soit dans l’esprit Elixir.
À demain.