« Nous les hackers nous [...] avions aussi une tradition d'acronymes récursifs qui consiste à dire que le programme qu'on crée est similaire à un programme existant. »
Richard Stallman
Les Deux Mystères, René Magritte
Dans la nature, on trouve différents objets qui font preuve d'auto-similarité. On peut aussi les construire artificiellement.
(D'après Wikipédia)
La récursivité est une démarche qui fait référence à l'objet même de la démarche à un moment du processus. En d'autres termes, c'est une démarche dont la description mène à la répétition d'une même règle. Ainsi, les cas suivants constituent des cas concrets de récursivité :
En NSI, nous abordons ces différents aspects.
Une fonction récursive est une fonction qui s'appelle elle-même. (Ou bien qui fait partie d'un ensemble de fonctions qui s'appellent mutuellement).
On a :
Par exemple, .
def somme_premiers_entiers(n): """Renvoie la somme 0 + 1 + ... + n >>> somme_premiers_entiers(5) 15 """ somme = 0 for i in range(1, n+1): somme += i return somme
def somme_premiers_entiers(n): """Renvoie la somme 0 + 1 + ... + n >>> somme_premiers_entiers(5) 15 """ if n == 0: return 0 else: return somme_premiers_entiers(n-1) + n
Les appels récursifs sont stockés dans une pile d'appels.
⚠️ Attention, par défaut, Python limite à , la profondeur des appels récursifs. Cela peut se modifier.
Voici, par exemple, une version naïve pour calculer un terme de la suite de Fibonacci.
Rappel : cette suite est
On commence avec , puis chaque nouveau terme est la somme des deux précédents.
def fibonacci(n): """Renvoie le terme d'indice n de la suite >>> fibonacci(6) 8 >>> fibonacci(0) 0 """ if n < 2: return n else: return fibonacci(n-1) + fibonacci(n-2)
Cette version est naïve, en effet l'appel fibonacci(5)
est effectué de nombreuses fois pour fibonacci(8)
et le résultat n'est pas stocké, donc recalculé à chaque fois... On utilisera la mémoïsation pour améliorer cela.
fib_dico = {0: 0, 1: 1} # valeurs initiales def fibonacci(n): """Renvoie le terme d'indice n de la suite >>> fibonacci(6) 8 >>> fibonacci(0) 0 """ if n in fib_dico: return fib_dico[n] else: fib_n = fibonacci(n-1) + fibonacci(n-2) fib_dico[n] = fib_n return fib_n
def fonction_A(x): ... ... ...fonction_B(...x...) ... return ... def fonction_B(x): ... ... ...fonction_A(...x...) ... return ...
La fonction_A
utilise la fonction_B
qui utilise elle-même la fonction_A
, a priori avec un paramètre qui dépend du paramètre donné en entrée...
⚠️ Faire des appels croisés est légal, cependant on veillera que cela fasse progresser le "calcul", donc sans rentrer dans une boucle infinie. On remarquera que ce principe est général, et que l'exemple simple suivant boucle à l'infini pour toute entrée n
supérieure à 0
.
def bizarre(n): if n == 0: return 9 else: return bizarre(n + 1)
Écrire une version récursive d'une fonction qui renvoie le nombre de chiffres d'un entier strictement positif.
Indice : Quel est le nombre de chiffres de , par rapport à celui de divisé par ?
Écrire une version récursive d'une fonction qui renvoie le nombre de bits égaux à d'un entier strictement positif.
Indice : S'inspirer de l'exercice précédent.
En partant du principe que :
Exemples
- ...
puissance(a, n)
qui renvoie .Indice : Penser au cas de base !
puissance(7, 20)
.Résoudre les problèmes au sujet de la récursivité sur FranceIOI.
D'après John McCarthy :
On considère : le nombre de façons d'écrire un entier comme somme d'entiers strictement positifs, sans tenir compte de l'ordre.
Par exemple, peut s'écrire de façons :
Écrire une fonction qui renvoie .
Le coin NSI + maths expertes
Douglas Hofstadter est l'auteur du livre Gödel, Escher, Bach : Les Brins d'une Guirlande Éternelle.
On y trouve en particulier certaines suites étonnantes.
Cette suite ressemble à celle de Fibonacci ou de Lucas, chaque terme est la somme de deux termes presque précédents.
La suite est définie par :
Personne n'a prouvé que cette suite est bien définie pour tout .
On ne connaît pas son taux de croissance.
Écrire un code qui calcule les termes succéssifs en vérifiant que chacun est bien défini.
; suite http://oeis.org/A005185
Les suites Hofstadter Figure-Figure et sont des suites d'entiers complémentaires définies par :
Les premiers termes sont :
Implémenter les fonctions
R
etS
en Python.
La suite est définie par :
; suite http://oeis.org/A004001