Correspondance Schröder (1)

Série d'exercices

Cet exercice fait partie d'une série :

Généralités

On rappelle qu'un arbre est dit :

  • enraciné : s'il possède au moins un nœud ; la racine
  • sans étiquette : les nœuds ne portent pas ici d'identifiant ni de valeurs
  • ordonné : l'ordre de ses sous-arbres compte

Dans ce cas, un arbre peut être modélisé avec une liste Python :

  • Une feuille (un nœud externe) sera représentée par une liste vide [] ; la liste de ses sous-arbres est vide.
  • Un nœud interne sera représenté par la liste de ses sous-arbres donnés dans l'ordre.
  • Un arbre sera donné par la représentation de sa racine.

Arbres de Schröder

Un arbre de Schröder est un arbre enraciné ordonné sans étiquette, ayant la propriété suivante :

un nœud ne possède jamais un unique sous-arbre ; soit aucun, soit au moins deux sous-arbres.

Ainsi, pour un arbre de Schröder :

  • un nœud externe (une feuille) ne possède aucun sous-arbre ; (classique)
  • un nœud interne possède au moins deux sous-arbres ; (particularité)

Exemples

est représenté en interne avec [[[], []], [], []]

est représenté en interne interne avec [[], [[], []], []]

⚠ Les deux arbres ci-dessus sont différents, d'où la qualification ordonné.

est représenté en interne avec [[], [[], [[], []], [], [], []], []]

Correspondance de Schröder

Pour un arbre de Schröder, on effectue un parcours préfixe et pour chaque nœud rencontré hormis la racine, on ajoute une étape à un chemin sur une grille qui part de l'origine :

  • ↗, codée \((1, 1)\), si le nœud est le plus à gauche (parmi ceux de son ancêtre direct)
  • ↘, codée \((1, -1)\), si le nœud est le plus à droite (parmi ceux de son ancêtre direct)
  • →→, codée \((2, 0)\), sinon.

L'objectif de l'exercice est de construire une fonction telle que arbre_vers_chemin(arbre) renvoie la description du chemin de l'arbre de Schröder passé en paramètre.

Exemples

donne

🐍 Console Python
>>> arbre_vers_chemin([[[], []], [], []])
[(1, 1), (1, 1), (1, -1), (2, 0), (1, -1)]

donne

🐍 Console Python
>>> arbre_vers_chemin([[], [[], []], []])
[(1, 1), (2, 0), (1, 1), (1, -1), (1, -1)]

donne

🐍 Console Python
>>> arbre_vers_chemin([[], [[], [[], []], [], [], []], []])
[(1, 1), (2, 0), (1, 1), (2, 0), (1, 1), (1, -1), (2, 0), (2, 0), (1, -1), (1, -1)]
###(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
Évaluations restantes : 10/10
.128013s3o_8bcdufvg/0ly n7apS.r1-me,(P2=4:twki9][5hx)6050i0C0K0u0N0p0b0r0h0p0u0b0b0H010K0N0v010406050b0j0B0B0u0y0q040w0d0p0j0:0d0s050n0`0|0~100^0v04191g051j0n1j1l1g0^0i0N0l0(0*0,0.0S0N0m0S0p1z0S0K0?050Z0g0p0C1u0+0-011y1A1C1A0K1I1K1G0K0g0d0i101H0y1h0K0S0(130b0v0u0s0.0G011M1w010k0#0C0s0u0B0C1G1.1:1^1O1{1K1~200?0a0r0F0y0d0v0d0b0N160s0r0X1,0y0y0C0h2l19230s1h0n1*2y0K1(1%1)0i250.1C0s1}2i1G1r1t0)1N2I0N2K0s1!1s1G0v2r1h2w2y2$0_1/2m2Q1_2V0y0}0p0?0r0z2v2*0@2)242,1O2.2:2=0G2^1:2`2w2H012 0u2;040r0c332x0^362}0.393b0r0I3f352*373l2=0R3p3h3r3j380d2/3a2=0V3w2{2+1v2~3B303c0t3G3i3J3k3L3D3c0f3P3y3R3A3C3m0O3X2|3Z3t040z0o3(3I2R3!3M0z2@1a2_3x3)3;3+0z323_343{3:2-3T3b0z3e413g3H3s460?0z3o4a3q3|453#4f3v4i434d4m3,3F4i1i2!192O2B0i2F370h1!211h4z1k4x2(4v4E0X2#3Y3;0M0?0X0k3p4c3z0L2=4W3Q3}0k0?0~0g2r0e0l0C0y0b0e0h0S0C0B2T4#4Q1_0=040E4{4k2~4)0y4+0C51441O4~0U0J3w0r5f0r4X3Z4S044U58374Z3c5n3z0s4(041/0y4E0j4:0e2Z0C1{0T574v4$4}0?505H4|53044*2r5r3Z4~0D3p5h5I5O4?4^4`5M520.5b5d4p5g5-5X5N3k0?0N5B2r4_4/5W5i3;0d0?0H5{5Y0.4_0?3.5,5.5f5|2-5=0e0X0y0s0N5`4i5/5(015~04606j6a2~0g0?285S3;4~5L2(623854566w5J040U615:6m0?0A6J6l643,5e686k590.5k0k3B6O6V6C040N6F5a0?5V6q6B0s0?0b0d0j4;5Q5G2$6U370d5p5$6`6r3k6t041}0{4/0u0K6_2_71016y6)5;5P555R5%6#5*6S6T5g7c5k0N4V6-6K6/6%6!6|5 6p706.6c5C5_0y7f7d0?5+2$067o7o7c7w5!4_187k7z040x7I7w0u0v0v1}0i7I6y6z7b6B6Q3^6A6K5U7y3z7/7*0?0U6I677O6{3z5k0C1C7t7C7v5=7@3Z6n0H7B2_803*6c6e6g6i7;6l4~7L3`7 687Q0?7S6 7-6K6n7Y7V5s4)7$7(7`4 7,347c7_8A5T6+895}6M7I8K8l7l7{7}7M8q8f4R0?830b7a8I6B8n7n8Y8Z6b048u7U8T7W8z8?8B5P8D0s7)8L6x5K8H2x8J0N0?408_8M046,866P95046698906H8W8p8q8s5v0~5y5A5C5E8(938*5K7Z6:6=6@7i9u4P8m8N7u6l7R4@7T8F9k427N7p7D8:9K8v348.1O8b8O6G0Q0P8,9n5w9q4;9s0N5F8F929E6#7!9C8F9b8e9n8;9M9%6B5k2r0K5z8=9`9R9|4p194N0C2y5C2y4I2z4B192C2B1Z1#2B0u1Jab4y1s2`0n0X0Z0#0b04.
Indice 1

En réalisant le parcours préfixe, pour chaque nœud, on veillera à identifier le premier et le dernier sous-arbre. Pour cela, on pourra obtenir d'abord le nombre de sous-arbres, puis en itérant, savoir s'il s'agit du premier, du dernier ou un autre cas.

Indice 2

On pourra compléter le code suivant

🐍 Script Python
def arbre_vers_chemin(arbre):
    def parcours_prefixe(arbre, chemin):
        i_premier = 0
        i_dernier = ...
        for i, sous_arbre in enumerate(arbre):
            if i == i_premier:
                chemin.append(...)
            elif i == i_dernier:
                ...
            else:
                ...
            parcours_prefixe(..., chemin)

    chemin = []
    parcours_prefixe(arbre, chemin)
    return chemin