Arbre généalogique

Un généalogiste amateur décide de représenter ses travaux avec Python.

Arbre généalogique de Carl Gustav Bielke

Etant face à l'arbre généalogique des parents, grands-parents, etc d'un individu, il utilise pour ce faire des arbres binaires représentés ainsi :

  • l'arbre binaire vide est représenté par None ;

  • un arbre binaire non vide est représenté par un tuple de trois éléments (sag, personne, sad) dans lequel :

    • sag est le sous-arbre gauche ;
    • personne est le nom de la personne à la racine de l'arbre ;
    • sad est le sous-arbre droit.

Il suit la convention de la généalogique qui veut que les pères soient placés sur la gauche et les mères sur la droite.

Ainsi l'arbre généalogique de base :

Arbre de base
Pierre         Pauline
    \         /
     \       /
      Jacques

sera représenté en Python par :

Arbre de base en Python
((None, "Pierre", None), "Jacques", (None, "Pauline", None))

Il arrive lors de la construction d'un arbre généalogique que l'on ignore l'ascendance d'une personne : l'arbre est interrompu sur certaines branches et est donc déséquilibré. Par exemple :

Arbre déséquilibré
Pierre      ?    ?         Martine
    \      /      \       /
     \    /        \     /
      Paul          Aline
          \        /
           \      /
            Pierre        ?
                \        /
                 \      /
                  Marion

Dans ce cas, les parents inconnus sont représentés par des arbres vides :

Arbre déséquilibré en Python
((((None, "Pierre", None), "Paul", None), "Pierre", (None, "Aline", (None, "Martine", None))), "Marion", None)

On cherche dans cet exercice à effectuer différents calculs sur des arbres généalogiques.

1. Personnes présentes

Écrire la fonction nb_presents qui prend en paramètre un tuple arbre représentant un arbre généalogique et renvoie le nombre de personnes présentes dans cet arbre.

Exemples
>>> une_gen = (None, "Moi", None)
>>> nb_presents(une_gen)
1
>>> deux_gen = ((None, "Papa", None), "Moi", (None, "Maman", None))
>>> nb_presents(deux_gen)
3
>>> trois_gen = ((None, "Papa", (None, "Mamy P.", None)), "Moi", ((None, "Papy M.", None), "Maman", None))
>>> nb_presents(trois_gen)
5

###(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

.128013idgcS4_: mb)t=s30na5(e,Nu+kPhv/1o2wylfrp050c0w0n0t0b0L0p0j0e0L0t0p0p0o010n0b0O010406050p0z0k0k0t0N0K040f0H0L0z0)0H0s050F0:0=0@0_0.0O041219051c0F1c1e190.0c0b0E0X0Z0#0%0D0b0d0D0L1s0D0n0,050S0l0L0w1n0!0$011r1t1v1t0n1B1D1z0n0l0H0c0_1A0N1a0n0D0X0|0p0O0t0s0%0I011F1p010M0U0w0s0t0k0w1z1%1)1.1H1;1D1@1_0,0a0j0C0N0H0O0H0p0b0 0s0j0Q1#0N0N0w0e2e121|0s1a0F1Z2r0n1X1W1Y0c1~0%1v0s1?2b1z1k1m0Y1G2B0b2D0s1T1l1z0O2k1a2p2r2V0/1(2f2J1/2O0N0?0L0,0G2o2Z0-2Y1}2#1H2%2)0,0I2-1)2/2p2A012@0t2*040q2{2q0.2~2=0%31330g362}2Z2 3c0,0u3f1b2T122H2u0c2y2 0e1T1`1a3q1d3o2X132.053v0Q2U3h3a010B0,0Q0M3m391o1H0J0,0j3Q3J3S3b0M0,0s0l0h2S0w0p1?0n0p3X2;3Z010+040v3:2!3=0s0,0@0l2k3`2 3@0m0i3f060j493W3R2K3L0,0b3P3D2|4b3Y4d3}043 414i2q4k3;4d0H3U040b3/4r044t3{4d0B0e0,0y100w423K3@464B484a4S2:4E1/3M042k0n0z0N114B4D2 0k0b0,0r474T4c2$0,0p0t0d4M3=3@0x3f4)3K4n0O0w0N0p102D4`4d4|4~4U3i4?0t0c5b4;1H0H0,0o5h4l4=4o0N404L4Q4:5o1H4X4Z4#4%2V4 3=4+2+5n4u1/5k040A5H4V2?3$3(3*3,0s3.581/3@3_4B5c505e4_5!5i0%445N2 5K5M4(5#3|5Q3)2k5T5V5)5w5+0,5Z2X5*305e5g5|5I1H5,4Q123G0w2r3*2r3z2s3s122v2u1S1U2u0t1C6d3p1l2/0F0Q0S0U0p04.
2. Nombre de générations

On définit le nombre de générations d'un arbre généalogique comme le nombre maximal de personnes rencontrées en remontant depuis la racine de l'arbre jusqu'à un ancêtre. Un arbre généalogique ne comptant qu'une seule personne a donc un nombre de génération égal à 1.

Écrire la fonction nb_generations qui prend en paramètre un tuple arbre représentant un arbre généalogique et renvoie sa hauteur.

Exemples
>>> une_gen = (None, "Moi", None)
>>> nb_generations(une_gen)
1
>>> deux_gen = ((None, "Papa", None), "Moi", (None, "Maman", None))
>>> nb_generations(deux_gen)
2
>>> trois_gen = ((None, "Papa", (None, "Mamy P.", None)), "Moi", ((None, "Papy M.", None), "Maman", None))
>>> nb_generations(trois_gen)
3

###(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

.128013idgcS4_: mb)t=s30na5(e,Nu+kPhv/1o2wylfxrp050c0w0n0t0b0L0p0j0e0L0t0p0p0o010n0b0P010406050p0z0k0k0t0O0K040f0H0L0z0*0H0s050F0;0?0^0`0/0P04131a051d0F1d1f1a0/0c0b0E0Y0!0$0(0D0b0d0D0L1t0D0n0-050T0l0L0w1o0#0%011s1u1w1u0n1C1E1A0n0l0H0c0`1B0O1b0n0D0Y0}0p0P0t0s0(0I011G1q010M0V0w0s0t0k0w1A1(1*1/1I1=1E1^1`0-0a0j0C0O0H0P0H0p0b100s0j0R1$0O0O0w0e2f131}0s1b0F1!2s0n1Y1X1Z0c1 0(1w0s1@2c1A1l1n0Z1H2C0b2E0s1U1m1A0P2l1b2q2s2W0:1)2g2K1:2P0O0@0L0-0G2p2!0.2Z1~2$1I2(2*0-0I2.1*2:2q2B012^0t2+040q2|2r0/2 2?0(32340g372~2!303d0-0u3g1c2U132I2v0c2z300e1U1{1b3r1e3p2Y142/053w0R2V3i3b010B0-0R0M3n3a1p1I0J0-0j3R3K3T3c0M0-0s0l0h0d1@0w0O0t2f0p3Y2=3!010,040v3=2#3@0s0-0^0l2l3|303_0m0i3g060j4b3X3S2L3M0-0b3Q3E2}4d3Z4f3 0441434k2r4m3?4f0H3V040b3;4t044v3}4f0B0e0-0y110w443L3_484D4a4c4U2;4G1:3N042l0n0z0O124D4F300k0b0-0r494V4e2%0-0p0t0d4O3@3_0x3g4+3L4p0P3-0p112E4|4f4~504W3j4^0t0c5c4?1I0H0-0o5i4n4@4q0O424N4S4=5p1I4Z4#4%4)2W513@4-2,5o4w1:5l040A5I4X2@0l0-0@0N591:3_3{4D5d523%3)3+2E3.3:5V1I5X5,3c5f4{5Z5j0(464 4*5!3~5$3*3,5*0b114C2Y5@3^0-5Y655x5:044_5h5?6b67040m0m49133H0w2s2T6p3q1m3s2v2x2t1T1V2v0t1D6s0F3r0/6F0S0U0W04.
3. Compter les prénoms identiques

Il arrive que certains prénoms apparaissent plusieurs fois dans un arbre généalogique.

Écrire la fonction compte qui prend en paramètre un tuple arbre représentant un arbre généalogique ainsi qu'un nom (au format str) et renvoie le nombre d'apparitions de ce nom dans l'arbre généalogique.

Exemples
>>> une_gen = (None, "Pierre", None)
>>> compte(une_gen, "Pierre")
1
>>> compte(une_gen, "Martin")
0
>>> deux_gen = ((None, "Paul", None), "Pierre", (None, "Jacqueline", None))
>>> compte(deux_gen, "Pierre")
1
>>> trois_gen = (((None, "Pierre", (None, "Jacqueline", None)), "Paul", None), "Pierre", ((None, "Pierre", None), "Jacqueline", None))
>>> compte(trois_gen, "Pierre")
3
>>> compte(trois_gen, "Jacqueline")
2

###(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

.128013idgc6S4: mb)t=s30na5(e,Nu+kPhv/18o2w7ylfrp050c0w0n0t0b0N0p0j0e0N0t0p0p0o010n0b0Q010406050p0z0k0k0t0P0M040g0I0N0z0+0I0s050F0=0@0_0{0:0Q04141b051e0F1e1g1b0:0c0b0E0Z0#0%0)0D0b0d0D0N1u0D0n0.050U0l0N0w1p0$0(011t1v1x1v0n1D1F1B0n0l0I0c0{1C0P1c0n0D0Z0~0p0Q0t0s0)0J011H1r010O0W0w0s0t0k0w1B1)1+1:1J1?1F1_1{0.0a0j0C0P0I0Q0I0p0b110s0j0S1%0P0P0w0e2g141~0s1c0F1#2t0n1Z1Y1!0c200)1x0s1^2d1B1m1o0!1I2D0b2F0s1V1n1B0Q2m1c2r2t2X0;1*2h2L1;2Q0P0^0N0.0G2q2#0/2!1 2%1J2)2+0.0J2/1+2;2r2C012_0t2,040q2}2s0:302@0)33350h382 2#313e0.0u3h3a3j3c320I2*340.0f3o2=2$1q2^3t2`040L3y3b3B3d3D3v040H3h1d2V142J2w0c2A310e1V1|1c3T1f3R2Z152:053Y0S2W3q3J010B0.0S0O3P3I2M010K0.0j3`3:3|0s0O0.3Y0k0Q0n0w412?3;0-040v4c3A430.0_0l2m4i314f0x3h403{2(0.2Q0k4p3r4f0m0i3o0j4G4u421;3?040b3_3*2~4I4d4k044m4o4P2s4R4j1;0I3~4M0p4t3z310B0e0.0y124b4X3/4S1;4f4E4?064H4~4Z4,0.2m0n0z0P134?503r0k0b0.0r4F4H4+3r0s0.0p0t0d4A4e0.4s585h3;5j040Q0w0P0p122F5o3|4r4*4v2^5k0t0c5G4J1J0I0.0o5M4^5I4U0P4n4=2X4}5g5H3d4x5S4!5O5Q5)315b5d5f4G5t3|4L4N5-5i0.5x5z5B5Y2:593;5P040o5R5s5$324x0I4z4?5?4_0.4{5Z4 5#5N5%04572X623|64676q6f1J5/042.4|4~6w0)4L53556p616D6a6o5`630.0A6N4T4749602~6K4f4h6e695v5l5n6!6m015F686*5v4y5D6g040m6R4#6P6^5U6T4a6;1J6Y6 6n5l5L6)5T0)6,6v6#6b6d2Z694C3y0F3-0w2t2U7k3S1n3U2w2y2u1U1W2w0t1E7n0F3T0:7A0T0V0X04.
4. Extraire une génération

On appelle génération \(n\) dans un arbre, l'ensemble des personnes définies comme suit :

  • la personne à la racine de l'arbre forme la génération \(1\) ;
  • ses parents forment la génération \(2\) ;
  • ses grands-parents la génération \(3\) ;
  • ...

Écrire la fonction generation qui prend en paramètre un tuple arbre représentant un arbre généalogique ainsi qu'un entier strictement positif n et renvoie la liste des noms des personnes situés à la génération n.

La liste sera ordonnée de façon à correspondre à la représentation graphique de l'arbre : le nom d'une personne apparaissant sur la gauche sera placé plus tôt dans la liste que le nom d'une personne apparaissant sur la droite.

Exemples
>>> une_gen = (None, "Moi", None)
>>> generation(une_gen, 1)
['Moi']
>>> deux_gen = ((None, "Papa", None), "Moi", (None, "Maman", None))
>>> generation(deux_gen, 2)
['Papa', 'Maman']
>>> trois_gen = ((None, "Papa", (None, "Mamy P.", None)), "Moi", ((None, "Papy M.", None), "Maman", None), )
>>> generation(trois_gen, 3)
['Mamy P.', 'Papy M.']

###(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

.128013idgcCS4«O mb=3aEN+qPh2w7yfrp6A_]:û)»tsén5([e,Ruk-;v/1.olx050c0S0L0p0b0(0M0k0e0(0p0M0M0n010L0b0C010406050M0V0l0l0p0B0z040g0%0(0V0}0%0O0k020p0l0C0Y0k0U0S170B0t0V0S0M050!1416181a120C041y1F051I0!1I1K1F120c0b0Z0=0@0_0{0v0b0d0v0(1Y0v0L10050-0m0(0S1T0^0`011X1Z1#1Z0L1+1-1)0L0m0%0c1a1*0B1G0L0v0=1d0M0C0p0O0{0w011/1V010A0/0S0O1l0S1)2a2c2h1;2k1-2n0l2p040a0k0u0B0%0C0%0M0b1g1i0+280B0B0S0e2K1y2r0O1G0!262W0L2423250c2t0{1#0O2m2H1)1Q1S0?1:2*0b2,0O201R1)0C2P1G2U2W31132b1i2=2i2`0B170(100#2T3511342s371;393b100w3f2c3h2U2)013m0p3c040o3q2V123t3k0{3w3y0h3B3s353u3H100P3K3D3M3F3v0%3a3x100D3R3i361U3l3W3n040y3K1H2 1y2:2Z0c2%3u0e202z0*1R1G2~0S303g3.3`0+423j3(0{0W100+0A3.3E49010x100k4f3T4h0O0A100d2m0S0B0p2S1z434g2?010 040Q4m484B0O10180m2P4G3%4B4D0T3K4l4A38100O4O3u4D0J0H4T060k4*4U4n4B4b040b4e4y3r4,4H4W044L4N4?2V4^4P2i0%4j4:1x4~04503u0W0e100r1h0S4Z3U4D4%574)4+5n3$5a102P0L0V0B4Y57595i100R0G3R5o4V3l100M0p0d5h4h4R4T5p3U4J040C4u0M1h2,5L4Q104S5x5P4o5H0p0c5O5F0{0%100n5,4-4`4|5g5l5E5?1;4/4;5=4_5G045w315y4h5/040n5;5$5-010l0b3d5Y2i5j5D5n4+5%4.5r0,5u643g665Z040R6i625T0B5V0O5X576o6j105C5`6n6d4/5s6s6051624s2,4v4x336d4D4F6G6d5R5I5K6$5|0{5N6c6,3v4X6R3u680X6?3U6f6h6+616-100J6`67100s734I4r4t6W0b1h6z704E7e6;045I5+6~6S7f5#656H626t4@7r5.106_6/6 6e6g043e7m4!713#0!45413/7L0!3=1y0L3@7Q2#2X1 212Z0p1,7N3=1E477n012P0l0F0A0p0W0S0F0v0o101q1s1u1w0k5k331L3h1F0f0,0L1.5V1e2K0k1w0L0k4v0C0b2M0p0k0N0e0B0b2P0k170b0;0O8k1w2I850k0m0S0p0V3`0V0C0k0c000N0-5T0;2M0i8d2Q2F0b5J1.0K8G1.1#0M850M0$1H81040q1i0S0A0A0,0k0(3W8M1.0e0v0p7{0k0p0C5T0(8d8k5u2I0A0T0k1h0k7.2J4l7K3u1?1!1$1(7(5q046P5v774`6U4u4w7c7t2V7v4C106#6Y6:6(5J7h6.7q6%6=7z7)6^9o1;6|7D9E7H9J6@759M3G796V9s7d7F5z7g9#5(7j5*9Q047p6u9w5R9u589w9L9S6{7C7E9A7A4#3.7J3{040$0k0j0B961-0;0Z3x0S938P0O0Z0%0z0N7|2b0B0=8_8{0A1h2R9t8j0-0O8c0+0;8Y8!960u0z26980c0%9baI0O0e8|0c1Q2K6V0=0S0(a90X0e0b8$807%0Eao8`1v8|8~aU910e934;aDaF0vaHaJayas4l1r9l8Q8f4u8:002m0M1r7!8Waaac931ya}afahaj7|0c2c0;0V2,0k2`0V0ZaU1-8:8r8x2M5V160S0$bA0k83281m3W852yax0k5T1f0k0M000p0Z0N2Pan3`0I850V0)a!1O3;0,0.0:04.

On peut résoudre cet exercice à l'aide d'un parcours en largeur de l'arbre.

Pour ce faire on crée une liste actuelle qui contient tous les nœuds non vides de la génération actuelle.

On met alors à jour cette liste en remontant à la génération précédente jusqu'à atteindre le rang de la génération souhaité.

###(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

.128013idgc6S4_]: mb)t=s30na5([e,NukPqhv/18.o2w7y9lfrp050c0z0p0v0b0S0r0l0e0S0v0r0r0q010p0b0V010406050r0C0m0m0v0U0Q040g0M0S0C0:0M0u050I0`0|0~100^0V04191g051j0I1j1l1g0^0c0b0H0(0*0,0.0G0b0d0G0S1z0G0p0?050Z0n0S0z1u0+0-011y1A1C1A0p1I1K1G0p0n0M0c101H0U1h0p0G0(130r0V0v0u0.0N011M1w010T0#0z0u0v0m0z1G1.1:1^1O1{1K1~200?0a0l0E0U0M0V0M0r0b160u0l0X1,0U0U0z0e2l19230u1h0I1*2y0p1(1%1)0c250.1C0u1}2i1G1r1t0)1N2I0b2K0u1!1s1G0V2r1h2w2y2$0_1/2m2Q1_2V0U0}0S0?0l0J2v2*0@2)242,1O2.2:2=0N2^1:2`2w2H012 0v2;040l0s332x0^362}0.393b0l0h3f352*373l2=0w3p3h3r3j380M2/3a2=0f3w2{2+1v2~3B303c0P3G3i3J3k3L3D3c0K3P3y3R3A3C3m0R3X2|3Z3t040J0t3(3I2R3!3M0J2@1a2_3x3)3;3+0J323_341i2!192O2B0c2F370e1!211h461k442(412x054b0X2#3Y3;0D0?0X0T3p3H370O2=4v3Q3}0T0?0d1}0z0U0v2u4j4o3|1_0=040x4A4p2-0?0~0n2r4S4N1O4P0A3p0l4w3z0u0?184L4*3Z4P0o0k4(060l4`4)4B4U040v2t0C0z0S1K4(4:3;0M0?0q564}4#0?0y4Z3:4~4W4Y4/5d0.4P0j3w4{4|4T1O4r040T3B5c5u3k0?0i5A4!0.0M4y042T5F5i2~0n0?4I0u4F5h374P4R5m5B010m0b0?3^2(5n014$5M3s4-5U3z4=4@4L4_5s4{574~2Z2s0z0X0u0p0z5-3z59045b4L5t5G5+5f5q5@5_5`5*5w5y0U643*4V6m585J5L695{2~4V5153555Y6b4P5?2$5^6g5s6u5C040r0v0d5:4;0?4%6t5*4,040V4H0r172K6O3;5,6S5Z6U6L0c6p1_66682$6a5N6J0v5r6G6H6i0?0b4u6(6b6*6M6-1O5I6}0r745H5J2V0p79010D0e0?0B17636A6?6c046D3`6`6`6I380?5}0e5 1}626#6.0?0L7C6v4 0V6W0u6,7m5V0?5X5)6)0?6L6N7N5;0?0o6_7s6=375w6~7e727M6;7u765K78707n7/7c7e7g7i7k7G5o0?7q346F7#6h7S6V2r7y607B7W3Z667F8b3}4V7J1}7,2_7u5W7}7v6K0v8k425*4=7!5_7u6U500p52547l7-5*6/7*7w877z618E7r846b5w2r8B0U4.8F5Z4P5g8f5j8o8Y8o5#5%8$0?6e8W8Q0?6k8I4 7e7/6s8.7n8z6x8D8+048-2_4`7u0e0J0?030l170l2K0l2r0u0H0M0b1L0F520l1K0%2V0m7;6E194m0z2y5}2y4f2z48192C2B1Z1#2B0v1J9v451s2`0I0X0Z0#0r04.

On peut résoudre cet exercice à l'aide d'un parcours en profondeur de l'arbre.

Pour ce faire on utilise une structure de pile dans laquelle on ajoute initialement la racine de l'arbre ainsi que sa hauteur 1.

Attention toutefois à l'ordre dans lequel on empile les différents nœuds : une pile répond au modèle « Dernier Entré, Premier Sorti » !

###(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

.128013idgcà6S4_]O: mb)t=s3é0na5([e,RNu+èk-qPh;v/18.o2w7y9lfrp050c0C0r0y0b0!0t0n0e0!0y0t0t0s010r0b0%010406050t0G0o0o0y0$0Y040h0U0!0G0{0U0x0n020y0o0%0O0n0E0C150$0L0G0C0t050Q12141618100%041w1D051G0Q1G1I1D100c0b0P0:0=0@0_0N0b0d0N0!1W0N0r0~050+0p0!0C1R0?0^011V1X1Z1X0r1)1+1%0r0p0U0c181(0$1E0r0N0:1b0t0%0y0x0_0V011-1T010#0-0C0x1j0C1%282a2f1/2i1+2l0o2n040a0n0M0$0U0%0U0t0b1e1g0)260$0$0C0e2I1w2p0x1E0Q242U0r2221230c2r0_1Z0x2k2F1%1O1Q0;1.2(0b2*0x1~1P1%0%2N1E2S2U2 11291g2:2g2^0$150!0~0n0R2R330 322q351/37393b0V3e2a3g2S2%013l0y3a040n0u3p2T103s3j0_3v3x0n0i3B3r333t3H3b0z3L3D3N3F3u0U383w3b0g3S3h341S3k3X3m3y0X3$3E3)3G3+3Z3y0S3/3U3;3W3Y3I0Z3`3i3|3P040R0w413(2;3}3,0R3d1x3f3T424a440R3o4f3q4h49363?3x0R3A4n3C3%3O4s0~0R3K4w2U2|0C2U2.2X0c2#3t0e1~2x0(1P1E4G2~3f3L054O0)4V4i2g0J0~0)0#4X3:4a0W3b4,3{4j0#0~0d2k0C0$0y2Q4E4y3V0}040A4;4$3k0~160p2N554q1/520D3L0n50430~0x5c3t520q0m5h060n5u5i4-360~0%2j5h5j4a0U0~0s5C5x5e0~0B544 5J3G580$5a0C5n510~5g4E5w4=2g0o0b4B5V3|5p0k3S5v5!565Q042N120!0+0r5I5#1/5F045H5Z5D2g520B5-4E5t5v631/4(040W1V1+5|5;3u0p0~2u5*4a525N315P3u5z5B5O5}0_5p6i5d0_5 020d0r0O6B3t5%0~476x6j525r685/5/6b5=0y6o645X6J3V0x0~0b6#3|5 612 5:6C6u045A6h6O6:5 0T6Y576=2D6|6z0~0A0q5.6T5u6V6;0t0y0d70015f6*4j5z4{0t1f2*7d7f626t6%047a0c7g2g6,7v6}6X6S766/3t6d0b4+7p6y6;6)7I6j6,6-3f7D6$5l7n0~6R2 697C6a7q0~5@0G5_4}7d6`7d7r0y0%0%2k7u6^5o727-7i0$7k0x7m7@5W04747B76786d0C0.5U805+7V757Z776t7F7H6.787r7t7y6D4/040b1v7M6_8q2^5{8u7E0e0~0F1f8a6s7J6Q8e8f6U7#6=6w8G7N0~6{8b7h047/7;0x7?8P6:6q6r4W8M8n8T6Z045Y8k8M7L8/7J5 0H8o016L457U82837X8K8g7J8i8_8m7b8_0U8q8s988w0U8y8=6j0J8B048D7 8!7^047W4g916T8l6v6@9n3V7,8+7z7:7=8}0A8%3q9u7s979A718-956(980~8^8z3V8{4e9x8c8~8J867$0*0G0$5m9T5k5?1u7(5`3$0Q4Z4H1F2}1w4J1w0r4L9|2Z2V1}1 2X0y1*9@0Q4J1C4#6:2N0o0j0#0y0J0C0j0N0u0~1o1q1s1u0n9q9H1J3g1D0l1g8x4{0y0naq0n2E9(0n5@7;2P4{0n0!003X0c2N0n0P0U7(0G0n0)0/2^0o0/0c2a0/0=aN8s0r0C0D0n1f0n0C0#0#2O0r1taN1,290$4O9(0/2k0n062?0t0v4|0x0raY00a5aQa}0n7k0G0t0K59aSaR0U2HaYa)aNaC6?a/0n0y0P2abc1+biaVblbn1,0d0y0G0e0Nbx4Obb4|0bad2kbc0fb50e1,aEaOa=agbr0Na52H1t0!1+2wbb0n0Ab74{2IaY1,aO2kagb:bJbLbNaF0G8sbhbp2H0q8S1M1H04ayaFaV2M0,bcbK0@0b0n1d0-8saM0G1ga b17|aI0v0eb27Ga?1g2YchbBaN00b|cFb bM1,0cbe1}0$0ca:0%c3a*cM2C2Ha:06bYaDc3aF4{2wbccN0U0pa.0xbSbua,0ta.0n2i2lbD1O2NaLb/c+btbD1}1gaQaS0AaUc;a+0R0IaS0P7j0ba=2KbY1^1,06aqc@dh0xc81F3ga80*0,0.04.