La récursivité
Exemple introductif⚓︎
On veut écrire une fonction qui produit l'affichage de triangles de n lignes, la première ligne contenant un *, la seconde deux * et ainsi de suite. Par exemple pour n=4, la fonction doit afficher :
Une des possibilités est d'utiliser une boucle, on dit que la fonction est itérative :
En observant la représentation ci-dessous, on constate aussi qu'il est possible de définir un triangle de 5 lignes par rappport à un triangle de 4 lignes, et plus généralement un triangle de n lignes par rapport à un triangle de n-1 lignes :

En effet, construire un triangle de n lignes c'est :
- construire un triangle de
n-1lignes - ajouter une ligne de
nétoiles
on vient de donner une méthode de construction récursive, qui doit se compléter en précisant qu'elle n'est valable que pour n>0. Cette définition trouve se traduit en python par :
Définition⚓︎
A retenir
Une fonction est dite récursive lorsqu'elle fait appel à elle-même. Par conséquent,
- une fonction récursive permet, comme une boucle, de répéter des instructions puisque le bloc d'exécution de la fonction est rappelé (mais avec des paramètres différents).
- une même fonction peut donc se programmer de façon itérative (avec des boucles) ou de façon récursive (en s'appelant elle-même).
- une fonction récursive doit toujours contenir au moins une condition d'arrêt (sinon elle s'appellera elle-même à l'infini)
Exemples corrigés⚓︎
Factorielle d'un entier⚓︎
La factorielle d'un entier est le produit de cet entier par tous ceux qui le précèdent (excepté 0). Cette fonction a déjà été programmé de façon itérative mais elle s'exprime aussi par rapport à elle même et donc peut être programmé de façon récursive, en effet :
\(n! = n \times \underline{(n-1)\times \dots \times 1}\) et puisque la partie soulignée vaut \((n-1)!\) :
\(n! = n \times (n-1)!\)
Cette écriture se traduit directement en Python par :
Il faut bien comprendre que par exemple pour calculer factorielle(4) python procédera de la façon suivante :
- calculer
factorielle(3)et le multiplier par 4 - calculer
factorielle(2)et le multiplier par 3 - calculer
factorielle(1)et le multiplier par 2 - calculer
factorielle(0)et le multiplier par 1 - comme la condition d'arrêt donc
factorielle(0)=1, on peut remonter dans le calcul et obtenir 24
Somme des éléments d'une liste⚓︎
La somme des élements d'une liste \(l = [l[0],\dots l[1]]\) peut s'exprimer ainsi :
- si la liste est vide c'est zéro (condition d'arrêt)
- sinon c'est le premier élément de la liste plus la somme de la liste à partir du second élément
c'est donc une définition récursive puisque nous avons exprimé la somme d'une liste à partir de la somme d'une (autre) liste. En python, il suffit de pouvoir exprimer la liste à partir du second élement à l'aide du tranche et on peut écrire :
Retourner une chaine de caractère⚓︎
Note
En cas de besoin, on conseille de revoir les tranches avant d'aborder cet exemple.
On veut écrire une fonctions récursive qui renvoie la chaine de caractère donnée en argument à l'envers. Par exemple envers("Python") doit renvoyer "nohtyP". Comme précédemment, afin d'écrire une version récursive de cette fonction, il faut exprimer l'envers d'une chaine par rapport à l'envers d'une autre chaine (plus courte). On peut remarquer que pour écrire une chaine à l'envers, il suffit d'écrire son dernier caractère puis l'envers du reste de la chaine ce qui se traduit en Python par :
| Python | |
|---|---|
Exercices⚓︎
-
Compléter le code de la fonction
occurrences, qui prend en argument une liste d'entierslet un entiernet renvoie le nombre d'apparitions dendansl.Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier.128013it3a;dv,FnT2S5éwbcy+14: f-up08)_9eklohrP=[sà6(]/mg7050g0I0c0e0b0K0R0y0s0K0e0R0R0P010c0b0C010406050R0B0X0X0e0N0t040n0L0K0B0@0L0k050W0~1012140|0C04051k1d1n0W1k0|0g0b0h0,0.0:0=0.0k0Y0B0e0Y0I0A0C0t0c0M1b0y0M0b0Y0M0K1P0M0c0`050%0r0K0I1w0/0;011O1Q1S1Q0c1Y1!1W0c0N1l1K0,170R0C0e0k0=0m011$1y010z0)0I0k0e0X0I1W1{1}221(251!282a0`0a0y0O0N0L0C0L0R0b1a0k0y0#1_0N0N0I0s2v1d2d0k1l0W1K2I1=1@1?1X0g2f1z0b0k272s1W1t1v0-1%2S2U0k0L2Y1W0C2B1l2G2I2/0}1|2w2!232(0N110K1W0e1N2B0z0=030G0G0s2)0I1S2%0L0A0T0A0v0`0v1d0e2:2?0{2=2e2^1(2`2|2~300I32013436383a2V3d0A20040m3j3l1}3n2G2R013s0e2}1l2 0M313335370#3C2(3E0d0`0d3J2F3m0|3N3q0=3Q3S053U3W3y3Y3B2T3D3e0w0`0w3+1e3-3o2@1x3r0L2{3R3u3V3w3X3A3!3}3$3e0o0`0o432/3.2?3O3=4d3_3z3Z394j3c3e0T0`0T4p453/483;4a3t3T3v3x4x3|3b3E0Z0`0Z4G3L4r3p4J3P4L4c4N4e4P3{4i4S3e0E0`0E4X2H4Z472#4$4b3?3^4f3`4h4z4.0A0H0`0H4?2I2,0I2I2Y2L0g1@2Q3:014y2X1u1l5a2.3m3,3L054y5p2e0b0g0=352G3E3g4N5x5z513#4B3f212j0I5G4y5I5C1W0W3k463O0J0`0#0z5r2H5V5i0q0`0y5#5v4_2_0z0`0L0s0s0B2A270s0I0R5,5%4#0_040U5~4I4`0k0`0K644s5i610x5,5+652_0r680b0R0c6a4!4`610i6f5 660`1c445s6h1(6d6o5.3r6j042T6n6y5$6A0=610F6t6M010L0`0A020Y0c0f6Q6b4#0k6G6I6D3O6C6K3n6-5V5F015A2?3E3G3@0y6;4,523~3F5L295N6=5H4A6^5S3k0y7a6g6#4`5X6H5!6-7c6p2_686!7k1(6T040P0P7n6E6N0`0Q0V6e6-0|6/3N6|0G5B3e3(5E5y745P767I712a5O4R6 7J3J7b7X7j7v017f2B0c5^6x2/7Z3O0X0b0`0D5,7C2;7E7L6?1}3E407K7S4-6 400y5M7 6~4k0A7}3J7?5q7^5G7H0A4m7~7M7T874m8372855Q4l78047X6u230s5D030y2t2(0k0i0y390R1#2T19260y0e0h2C0y1!0y7%7)0y0S8Q2 1,2U0y2,0p0s0p0#0k0c0I7=6*7F8f4D8i6}8q3d7Q738@7O8_2I797b8v3r0`5a8H0k5{0G257*3m7,5i7q7t7i923;6(8+6*6c0`637D7d7l04699q7o7w040Q9m4#7q0A9A4`7.3h9E23610V7u3O9f9g7+9i3P6w9I6B0`6P9h6R8x0`8z0l0N0B1#5|0c8S0I0X0C0.8(8#120y0v8E0j3R8H9?0N0y7;7B8/7_7G6@3e4U8?75534U8n7R8j8087a87W916R7$0$7)9M5i6704955`0I992Tap9B0`0uay6v045=5@5_975|9U9x9p7@9r939taK01610Q7AaN9w6S6UaR9G043i9v7!9K6s9YaO3;9Ta(6+9W8.a:8:a60A4:a97N534:ad8{aa6 a{8aa38ea_55a|8k5J55b08p8}b93+al0`1%0I0N6J9Q6RaraF5^2BaI5}a:9n629zbx4#a#a%aWa)0`a+bpa-01a#3*bB6qbHaC23bMaRa*bR1(bTbO9Ja=a,aX9ObW0=a#3Ia26/0W5u1o2-1d5d1d0c5fb^2O2J0e1Z5bb?5m7C0#0%0)0R04. -
Dans le bac à sable, écrire une version récursive des fonctions suivantes :
-
Fonction
puissance, qui prend en argument un nombre \(x\) et un entier \(n\) (positif) et renvoie \(x^n\). -
Fonction
palindrome, qui prend en argument une chaine de caractère et qui renvoieTruelorsque cette chaine est un palindrome,Falsesinon. -
Fonction
maximum, qui prend en argument une liste d'entiers et renvoie le maximum des éléments de cette liste.
-
-
Modifier la fonction
triangle_recursifde l'exemple introductif afin d'afficher le même triangle mais "pointe vers le bas". -
Complète le code suivant qui retourne le PGCD de a et b
Note
Si \(a >= b\):
l'algorithme d'Euclide nous donne l'égalité : \(pgcd(a,b) = pgcd(b, a - b)\).
###(Dés-)Active le code après la ligne# Tests(insensible à la casse)
(Ctrl+I)Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)Entrer ou sortir du mode "plein écran"
(Esc)Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier.128013it3a;dv,n2S5éwêbcy14: f-up08)_9eklohrP=s6(/mg7050g0G0c0e0b0I0O0w0r0I0e0O0O0N010c0b0A010406050O0z0S0S0e0L0s040l0J0I0z0/0J0j050R0_0{0}0 0@0A04051f181i0R1f0@0g0b0h0%0)0+0-0)0j0T0z0e0T0G0y0A0s0c0K160w0K0b0T0K0I1K0K0c0=050Y0q0I0G1r0*0,011J1L1N1L0c1T1V1R0c0L1g1F0%120O0A0e0j0-0k011X1t010x0!0G0j0e0S0G1R1?1^1}1Z201V23250=0a0w0M0L0J0A0J0O0b150j0w0W1;0L0L0G0r2q18280j1g0R1F2D1-1/1.1S0g2a1u0b0j222n1R1o1q0(1Y2N2P0j0J2T1R0A2w1g2B2D2*0^1@2r2V1~2Z0L0|0I1R0e1I2w0x0-030E0E0r2!0G1N2Y0J0y0U0y0t0=0t180e2+2.0?2-292:1Z2=2@2_2{0G2}012 3133352Q380y1{040k3e3g1^3i2B2M013n0e2^1g2`0K2|2~30320W3x2Z3z0d0=0d3E2A3h0@3I3l0-3L3N053P3R3t3T3w2O3y390u0=0u3$193(3j2/1s3m0J2?3M3p3Q3r3S3v3V3^3X390m0=0m3~2*3)2.3J3-483;3u3U344e37390P0=0P4k403*433,453o3O3q3s4s3@363z0U0=0U4B3G4m3k4E3K4G474I494K3?4d4N390C0=0C4S2C1j2(182T2G0g1/2L3+014t2S1p1g2%0G2)3h3%3G054t53290b0g0-302B3z3b4I5b5d4c4u4)3a1|2e0G5k4t3W4w5o2D3f413J0H0=0W0x554/4D2W010o0=0w5F59425I0j0x0=0A0T0r0g5N5z4{0;040Q5Y5H2;0=0e5(4n5!0=0i5-4V5Q0=0q5=5P1~5#0D0v5N0@3 563I5j015e2.3z3B3/0w654%5m3_3A5p245r665l5u691R0R3f0w6s5M5)1Z5B040b5E622C6u5.4W0j5^5N6D5?1~0J0=0N0N6I5Z4W0S0b0=0B5`3J5#5 6B3i6#5z6d0E5f393Z5i5c6l5t4v3Y6i255s4M6g6-3E6t6~6J5{6w0=2w0c0z0L176#704o5+6Q6v0-0r5h030%0*2s1W0q0*0G0i1;0j1o2q2s02030d0F0f0}0L0p0c606X6)6+0y3{6.6_4(6g3{0w5q7M6f4f7J6p6r6t6R5I6x6z7d6E5@045,797Z6L0=020I0c0f7%6K3m6H6%7e016Z7F7{4n7H684g3p6)6;5n4h7Q6j7S6n845x046 7Y7|6x7476782*7a4{6G045U5W6X5/5$8v6F7`2,7|5#5;807^3,7c8F710-5}7@8K4|7h2i0J760w0T0}0W0L0w2`020T7=0N0w0q7q220w0A0G2?141^0c8Z0w0X8)7 8B816/671^3z4y7L6:6`7U4y8a6^947N967W8g8i7(1~8k0X8m8N7b8s5V5X8J6Y0=5%9q8q8A548C5:9l9v7*9A4W6M040y9D7)5_9u4W8M7,7|7g0=7i2`320S0A0I0n0c8/8{9x8}5k7I4P936e8d386@6k9,6=399*3E618|5a8~6*830y4+9+6m9=9 9/8ca3a03$8j5+0+8/7E9O9g7_9n8u9L5I5#9t9`8O6T4z6Wak5|9zaf8G01aq3C3}at1Z9N8o7-1Z9F6O9I1~az0t3D6#9_540R584:524=4 180c4^aY2J2E0e1UaV0R4?610W0Y0!0O04. -
Écrire, dans le bac à sable, une fonction
cbinomialdoublement récursive qui calcule les coefficients du binomes selon la relation :\[ \binom{n}{p} = \binom{n-1}{p-1} + \binom{n-1}{p} \] -
La suite de Fibonacci est définie par la relation de récurrence suivante :
\[ Fibo(0) = 0,\quad Fibo(1) = 1 \]Et pour tout entier \(n > 1\) :
\[ Fibo(n) = Fibo(n-1) + Fibo(n-2) \]Complète le code suivant qui retourne le terme de Fibonacci :
Fibo(n)###(Dés-)Active le code après la ligne# Tests(insensible à la casse)
(Ctrl+I)Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)Entrer ou sortir du mode "plein écran"
(Esc)Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier.128013Ait3a;dv,EFn{2S5wbcy+14q: f-up08)_}9eklohxrP=s6(/mg7050h0L0d0f0c0N0U0A0t0N0f0U0U0T010d0c0E010406050U0D0Y0Y0f0R0u040p0O0N0D0^0O0m050X0 1113150}0E04051l1e1o0X1l0}0h0c0i0-0/0;0?0/0m0Z0D0f0Z0L0C0E0u0d0P1c0A0P0c0Z0P0N1Q0P0d0{050(0s0N0L1x0:0=011P1R1T1R0d1Z1#1X0d0R1m1L0-180U0E0f0m0?0o011%1z010B0*0L0m0f0Y0L1X1|1~231)261#292b0{0a0A0S0R0O0E0O0U0c1b0m0A0$1`0R0R0L0t2w1e2e0m1m0X1L2J1?1^1@1Y0h2g1A0c0m282t1X1u1w0.1(2T2V0m0O2Z1X0E2C1m2H2J2:0~1}2x2#242)0R120N1X0f1O2C0B0?030I0I0t2*0L1T2(0O0C0G0C0w0{0A0w1e0f2;2@0|2?2f2_1)2{2}2 310L33013537393b2W3e0C21040A0o3l3n1~3p2H2S013u0f2~1m300P323436380$3E2)3G0e3i0e3M2G3o0}3Q3s0?3T3V053X3Z3A3#3D2U3F3f0x3i0x3.1f3:3q2^1y3t0O2|3U3w3Y3y3!3C3%403)3f0q3i0q462:3;2@3R3^4g3|3B3$3a4m3d3f0V3i0V4s483=4b3@4d3v3W3x3z4A3 3c3G0!3i0!4J3O4u3r4M3S4O4f4Q4h4S3~4l4V3f0G3i0G4!2I4$4a2$4)4e3_3{4i3}4k4C4;0C0K3i0K4_3P4v3?4~4P3`4R4j4B3(4E3g0F0{0w0F5b4{4w4*505i535k4D3G0w3h045C5b1p2.1e2Z2M0h1^2R5e4B2Y1v1m2-0L2/3o3/3O054B5W2f0c0h0?362H5B3w5(5*545l5-0A2k0L5:5z565D3.4L4}0M0{0$0B5Y2I493R0r3i655$4|2`0B0{260s0O6b675e0`040W6k5 2`0{1d475Z6r1)6n0H0z6b0}6v663Q5/015+2@3G3I5h6H4/55413H225^5`4U6R6M0X3m0A6#0A6l4(61040c646E3J6(4}0m6t6b6%6x0?0O0{0T0T6@6:240Y0c0{5r6.706y0{6B6.6D2=6G5)6I0I5,3f3+4Q6O5;5A7j6T2a5_7g5{6R7k3M6$7y6^5d6)0{2C0d0D0R6u2:7A4%4}72746C6q4v7m7i0C437l7f6P5=427q2b6V4:6R7V7x6$770?6*4C6-7J7-3S6?6.7K6d1)6{046}6 6_017N5E7Q7L246n7a4t852x7S6K4o5.7X7n564p5@7r7%6Q4n0C4p2J6!7z6#7?6*7E7G7I3o7`3R833k7b8b0A8d1~3G4G7W8n7Z0C4G8l7$7t6W8p8M7+8v817/0+0L8H6m797P767e5:7T4X8N8U7(8p4X8S7s7Y7o0C8:8Y7z8w7D0%8z807B6;6g0c6i8(4(6n6p8,966s048A3O8C5e7}0C95861)8E9b4}6z9p7{6`0{0v9w4w989a9f9q0?9d9t9h9j2I9l4(9n9B5e833L9F9x019v8G9U8I8h7T4?8;8{564?8_8O8|9%3M7c5X8-7g7T589(8i6R589,8=8o5m9_5~9g1)0t5D030A0k0Q0L0Y0E1#2y02030e0K0g1a0*0c0U0f2F9Y7d7R9#8e5n8g9-5|5o9~9)6R5q1X6Z6c9C9i9Q9O6|aL7M735E758a9Z8J0m5B5}307m7u8p5C7#8`9{a$5}aH7?0m0s0{2-2U0d9J786oa^0?ap6ga{010U3I020y0D0O0d0g0l990O9eat9Gb0aQ0na 6=aK9Z5e2u0{0Ja b10{0H0A0Tb3b5b7a 6n0jaO9h6h6jbl9c0{bc9=a43@7^bd9V6z0H6@9N4}a60{a80b0B260t0P1$0l0W5qbt0T0A0q4ras5X0X5#5H5V5J5S1e0d5Mb{2P2K0f1!b^0X5K6D0$0(0*0U04.
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)