Écrire les entiers sans les chiffres (POO)

On souhaite dans cet exercice créer une classe Entier permettant de représenter des nombres entiers positifs ou nuls, de tester leur égalité, de les additionner et les soustraire.

On fournit donc une classe Entier dont l'interface est détaillée ci-dessous dans le cadre d'un exemple :

  • a = Entier() : crée un objet représentant l'entier \(0\) et l'affecte à la variable a ;

  • a.incremente() : augmente la valeur de l'entier représenté par a de une unité. a représente désormais l'entier \(1\) ;

  • a.est_nul() : renvoie le booléen indiquant si a représente l'entier nul. Dans le cas présent, cette expression est évaluée à False ;
  • b = a.copie() : crée un entier de même valeur que a et l'affecte à la variable b. Ces deux objets sont distincts : modifier l'un n'a pas d'incidence sur l'autre ;
  • b = b.decremente() : diminue la valeur de l'entier représenté par b de une unité. b représente désormais l'entier \(0\), a représente toujours \(1\).

La méthode decremente génère une ValueError si l'entier auquel on l'applique représente \(0\). Il est en effet impossible de représenter un entier inférieur à \(0\) dans le cadre des entiers positifs.

Il est aussi possible de tester l'égalité de deux entiers en faisant par exemple a == b qui, dans le cas présent, est évalué à False.

La classe Entier est fournie pour information ci-dessous.

Classe Entier

Les entiers sont représentés par des listes imbriquées. Ainsi :

  • \(0\) est représenté par la liste vide [],
  • \(1\) est représenté par la liste contenant une liste vide [[]],
  • \(2\) est représenté par la liste contenant une liste contenant une liste vide [[[]]],
  • etc...

Le code ci-dessous est fourni à titre indicatif. On doit résoudre l'exercice en n'utilisant que les méthodes est_nul, copie, incremente et decremente.

class Entier:
    def __init__(self):
        "Crée un entier égal à zéro"
        self.liste = []

    def est_nul(self):
        "Indique si cet entier est nul ou non"
        return self.liste == []

    def incremente(self):
        "Augmente la valeur de cet entier de un"
        self.liste = [self.liste]

    def decremente(self):
        "Diminue, si possible, la valeur de cet entier de un"
        if self.est_nul():
            raise ValueError("L'entier est nul")
        else:
            self.liste = self.liste.pop()

    def copie(self):
        "Renvoie un entier égal à cet entier"
        nouveau = Entier()
        while nouveau.liste != self.liste:
            nouveau.incremente()
        return nouveau

    def __eq__(self, autre):
        "Teste l'égalité de deux entiers"
        return self.liste == autre.liste

    def __repr__(self):
        "Renvoie la représentation d'un objet de cet entier"
        return f"'Entier' représenté par {self.liste}"

La méthode __eq__ a un statut particulier. Elle fait partie des méthodes spéciales de Python. Définir la méthode __eq__ dans une classe permet de tester l'égalité de deux instances de cette classe en faisant a == b. Dans ce cas, Python exécute l'action a.__eq__(b).

De la même façon, __repr__ est une méthode spéciale permettant de représenter un objet dans la console.

On souhaite mettre en place l'addition et la soustraction d'entiers. Pour cela on complète les méthodes spéciales __add__ et __sub__ qui sont appelées lorsque l'on exécute a + b et a - b. Ces méthodes créent chacune un nouvel entier représentant le nombre correspondant à l'opération demandée.

Attention, certaines soustractions sont impossibles dans le cadre des entiers positifs ou nuls. Dans ce cas la méthode __sub__ générera une erreur du type ArithmeticError.

Exemples

Ci-dessous, les objets zero, un, deux et trois sont des instances de la classe Entierreprésentant les nombres entiers correspondants.

>>> resultat = zero + zero
>>> resultat == zero
True
>>> resultat = un + deux
>>> resultat == trois
True
>>> resultat = zero - zero
>>> resultat == zero
True
>>> resultat = trois - un
>>> resultat == deux
True
Générer une erreur

Il est possible avec Python d'interrompre l'exécution du code en générant une erreur. Pour ce faire on utilise l'instruction raise <Erreur>. La méthode decremente génère ainsi une erreur : raise ValueError("L'entier est nul").

Dans le cas présent, si une soustraction impossible est effectuée, on saisira raise ArithmeticError("Opération impossible").

Python propose de plus un mécanisme permettant d'intercepter de telles erreurs sans interrompre l'exécution. Cette structure utilise les mots clés try et except et est utilisée dans les tests de cet exercice.

Contrainte

Dans tout l'exercice, il est interdit d'accéder aux attributs des objets de la classe Entier.

On n'utilisera que les méthodes incremente, decremente et copie.

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

.128013s3_8èufvIy n7GaS1me(P24C:Vjtwi]D[hE)6Oo;bcdgx/T0làqAp!.rL-,}=zk95R{é050R0t0C0p0E0X0b0l0Q0X0p0b0b0-010C0E0#010406050b0g0s0s0p0(0k040q0N0X0g180N0m0l020p0s0#0O0l0=0t1i0(0Z0g0t0b050U1f1h1j1l1d0#041J1Q051T0U1T1V1Q1d0R0E0i101214160I0E0S0I0X1-0I0C1b050{0P0X0t1(1315011,1.1:1.0C1_1{1@0C0P0N0R1l1^0(1R0C0I101o0b0#0p0m160w011}1*010h0}0t0m1w0t1@2l2n2s1 2v1{2y0s2A040a0l0v0(0N0#0N0b0E1r1t0_2j0(0(0t0Q2V1J2C0m1R0U2h2+0C2f2e2g0R2E161:0m2x2S1@1#1%111~2^0E2`0m2b1$1@0#2!1R2)2+3c1e2m1t302t350(1i0X1b0l0r2(3g1c3f2D3i1 3k3m3o0w3r2n3t2)2@013y0p3n040l0c3C2*1d3F3w163I3K0l0x3O3E3g3G3U3o0;3Y3Q3!3S3H0N3l3J3o0L3)3u3h1)3x3.3z3L0n3?3R3_3T3{3:3L0e3 3+413-3/3V0:473v493$040r0W4e3^314a3|0r3q1K3s3*4f4n4h0r3B4s3D4u4m3j433K0r3N4A3P3@3#4F1b0r3X4J3Z4v4E4b4O3(4R4C4M4V4i3=4Y4L3,4x3~4(404w4N4i464-484/4#0r4d4?4T3`4#0w4k4|4D4~3|0w4r3c4Z4*4:0w4z584)4g5b4I5e4.4U554Q5j4@5l440w4X5o4}424 4%5u535w554,5z4!554=5E5a4 4{5I5g4#0c515M4^3|0c574t5f5S440c5d5W5k545Z5i5$5p5(3K0c5n5+5v4o5Z5t5;5A5?5.5y5_5F5Z5D5~5J5T5H625N5T5L665Y3K0x5Q6a5q6c5V4B5X6g1b0x5#6j5%5B440x5*6p5,6r6c5:6v5=4h0x5^6A5`6C5}6F5 6c616J636s656N676s696R6b1b0;6e6V6l040;6i4K6q5{6X6o6)6w6+6$6u6.6B4:0;6z6?6G6^6E6{6K6X6I6 6O3K0;6M736S756Q786W6$6U7c6#0L6Z7g5-1b0L6(2+390t2+2~2.0R2=3G0Q2b2K0^1$1R7q3b3s3Y057y0_7F5=0/1b3w7H6*0D3o7Q6/0m0Q1b0J0m180t0(7U5=1a040z3)0l7.0l6k1 7N040_0h7(5`7S3L7`3G0h0s1b0d0d332U837~3,7*0u88490P7*0b0t0X7_4R7;167*0K7,4Y7/8r7:6*0b2q04010y0(0@1|0g1t2x7#0(0l0@0S3J0l0Y0l0.0@2P017-8s7.8l018e1b8g8i8c4n0N1b0%8$3j1b1:0b0C0t3Y8t6/8(040-8=8W7*0H0F3)068r8W7?7^8+1 7|7:8k6*0m0h1b1H0C0d0m0g0X968m1b8b9a6/8Y048!8j3e6*8n8p588U8V8u8w010j0m1#1F1|2T100`0l8F0E7$9N8/0l9i0X0l0N0g9T1s8S8q9A931b2!0C0g0(0m8{6*9r9t9l018^8*9p6B8-0E8/8;4R8?5=8^0-8`a08|1b8~90926*940t9u7G7R7T9`6G9d04330Q2!2J7!9 9v6/8a9?9;8haf3Da7048o8T8U8W8v1b010!0g0Saq8:0l120l0i3J0t9,0l2X0Q9M9O9Q2X8D9#9z9%9:8fay9?9^9?0m9|9~9/8@1ba53ca15`8}awa,8#aj3Ga/b24*a=8:9?7*8 4Y917/9(7@ae9?98a:al0_ao1C8Fasagau9na 8Za-b5499xaE8saG9D0G0E0s331G0+0l9K2R140E1`0tbJaQaS1{aVaXaZ7!9P8Ha$a;bAab6/7?0Eaz2*a|3Gaxb1ata28)a:9e8/9h9jb99naD9$9Abeac9)0|8ga@6B2K0A3J1G0J2Z3.b}049ob=5`aH8x0)00a!8H9f9T9ja(br7)1b0Kb%c2b)9e0~bqaA9w1b9y4tc1b(5=b:b,7L5`b4cj3#b7cEb-8Wa3c75`cNa.b@bx4wcUc$049_cSb6042R0#cg0ucybccL5`adcO8Wbjc(3jal7y0#9Pc?bu9sbwc.bycxcI4Bc1bCaI1B0m0i0N9P0l8D9NbY9Q8J8L8NaY0Cdp8Gcudea*7V1b350g0i0t0p0gcZb3a_dKc/7Z8Gc?c^a)aFc3040D1,1{dN4gdD9XdGdIc+c-cv6Gc*a66*8^0$a`3sb.3,c#d01 cRd,cT048.b8d{9m7+czdUdC04dEd(dJe39@c%dac)am7WapbpdRe6d^497?9*9,9.d/e8eadHec58bd9BcBbgc}ah7}ed80820d0t0Z87edavedd`eg2t7*0+d!ehdI2/cVcP3Gbzc0bB9CaI0V9f1|0X00ds1:0C0@aW1|0_0g0TdxbZ0bdz3PdfdVer9-eW2teRd~3,d}cFe8e1e!eo8%a_d?3Dfg8,04eY2!d*b^e09}e2ezc`3Gc|biaieS2F8104832!39eNfBe4cif98db0eEbsaCddf1dB5=cl01didkdmaQfG8A8g7!0p2VaW00do0N0P0B9MbWdwcpf01cf2eCf4eta{aG0p1bfPfV9D00dPbZ000lf$0@f(e?0l2m8H9?2T1b0?d79=edfb2*8Wa;fsa?edgj040,gi9DaacA7M1b95edc fJ2ufD830p0R0RfIfM4nePgIf8fccw04eVeu9{fn1qfpeOdc4l3G989%gv0RaI01f_59490bg/3L9A0!gN2U0E1s2`9Lf@dq8H8Ndofo1|cpg*3,g^3o9AfYdl8C1tew9Vha523Ghdg`8Ug;g=f{g!2!1f0X0{0Cf6d|dMgZc!fOfqedgsd3d5g(chdScJfUd-048:1xhB16cYhEd h8hHgIhJ2QhLgI8ahOdAe7gDdWdYffcX7|35hAhYc/hTc=goefgQfm9fb{9khMc@fSf`cKeBg!h|h#i03xgE2#ekareme(huhRhw9jhzidgVhRaniifuiefKh,fTh.c{9)0`eshV3HiDhxiqc_gCiCeDfzeGgIeIfE0d1f0PgPise$bteQhGhMgYf 9b1bh!hMb 5R2tg,aFg.g:g=aGg_c11n0g8/0(0|dwh7g$h9h48M9L1p0E0*0Q0Ehbg@i`hf2xfZhi9ZdF8he}7$jd4nhpc10o0@0m0f2!dnh10!0(2U0I2J180Qcd2P8H9Ke/2Q8Qf*g 1t2!djhhjyjnjJ2/0E2$bo7!9Tds18cOg?jqjfhrg;engriIipf*iGhXi)9qi$gIgpe#c/hKe!aBc@j/i*hS1Ch}j_b?8_iGgsi,j|h iYj h(k1cGhNk4eCdX2wj@h@0Nh_k9hRich~c,fri29UdRi7eAcKbfb+kcj;hyj?kyd+khd#04kBb|i5i.hPi9fw3,eqc5h=9b2KjAjCjEjYjHcfi5gzaI0M0#jNf+bFbM2TbPf_aBizi8i9j:k6hUkNfrbmivkkfQk3ilhQd iokLkuixeekzhIigbnaNl9gWlbdTe)f|iEf5h`kQlfiK5e0U7J7r1S3a1J7t1J0C7vlJ2:2,2a2c2.0pbP7s7C1Pj~49ap0d0h0p0/0t0d0I0c1b1B1D9I0 i71S3t1Q0yaZ0T7$jbaYgf7$jEe^bK1|l#bG1:1j9}9Q0pdG0QaP1H0l0s0@2h7z0 2l0@jbaT0 2X0v0kmi0m0%0l0Mj3j71{0 aNjP0m8Bmp2n0 1{bK0gf;0CbJ1sga2x7y7!jx8Fjxh8l:l=1d9j3t1:l?1RlDiT2`eNm*0l0zaWmhl 339J0Ee^e{9Wf:0`mk1sdw1#0h0h8Q8F0 8b1Ce9kt9N1F3J1Jn90KgY1Z1Jm%1dnl1Um)7ziT0S9g0d1Jm.m:0Rm=3lm@bKm_jLm}dw1Fm_iV2UaP0pmfmh0I7z9Rdwi~jYhT8FmKk?jBaUh5j70gm_2m14e@2x0l1j0S1gnWn80s040S2!f*9Q2h2nnfn?nhmZnk0Em$o37Inq830Sl(nulCnqm/m;8:nAh1jK00f/mM0lnHmK0PnKaQmgmi2Xcr1fnY9PaV9X8I8K9Vdu8hn%gf1~n+1tn.n:j#n=n@n_og9Wcqndi4nggYnnm%o67K83hym-odnxnzbGoinDoknFonoHnJdwosnOnQowjXjZaN0l33n4nZaVoFj8oIn*dpn-0(n/o oPmA0 n|etoXo2o4npo$0d1{o)7Koenyogo-m^aPo:omooo@nLnNouh99Sp18Qoz8HoBe;j6aYp6n)0boKpapcn;05n9pfoTnc0gne0Upj0UoZo5m*830s9jpq7roep.hy191:e.py9MpA0goqo^nMotnPovdwpOoHpQpSoMaNmvhgdmdohkm|mM9_nn0Um#1d0U0_0{0}0b04.

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

.128013s3_8èufvIy n7GaS1me(P24C:Vjtwi]D[hE)6Oo;bcdgx/T0làqAp!.rL-,}=zk95R{é050R0t0C0p0E0X0b0l0Q0X0p0b0b0-010C0E0#010406050b0g0s0s0p0(0k040q0N0X0g180N0m0l020p0s0#0O0l0=0t1i0(0Z0g0t0b050U1f1h1j1l1d0#041J1Q051T0U1T1V1Q1d0R0E0i101214160I0E0S0I0X1-0I0C1b050{0P0X0t1(1315011,1.1:1.0C1_1{1@0C0P0N0R1l1^0(1R0C0I101o0b0#0p0m160w011}1*010h0}0t0m1w0t1@2l2n2s1 2v1{2y0s2A040a0l0v0(0N0#0N0b0E1r1t0_2j0(0(0t0Q2V1J2C0m1R0U2h2+0C2f2e2g0R2E161:0m2x2S1@1#1%111~2^0E2`0m2b1$1@0#2!1R2)2+3c1e2m1t302t350(1i0X1b0l0r2(3g1c3f2D3i1 3k3m3o0w3r2n3t2)2@013y0p3n040l0c3C2*1d3F3w163I3K0l0x3O3E3g3G3U3o0;3Y3Q3!3S3H0N3l3J3o0L3)3u3h1)3x3.3z3L0n3?3R3_3T3{3:3L0e3 3+413-3/3V0:473v493$040r0W4e3^314a3|0r3q1K3s3*4f4n4h0r3B4s3D4u4m3j433K0r3N4A3P3@3#4F1b0r3X4J3Z4v4E4b4O3(4R4C4M4V4i3=4Y4L3,4x3~4(404w4N4i464-484/4#0r4d4?4T3`4#0w4k4|4D4~3|0w4r3c4Z4*4:0w4z584)4g5b4I5e4.4U554Q5j4@5l440w4X5o4}424 4%5u535w554,5z4!554=5E5a4 4{5I5g4#0c515M4^3|0c574t5f5S440c5d5W5k545Z5i5$5p5(3K0c5n5+5v4o5Z5t5;5A5?5.5y5_5F5Z5D5~5J5T5H625N5T5L665Y3K0x5Q6a5q6c5V4B5X6g1b0x5#6j5%5B440x5*6p5,6r6c5:6v5=4h0x5^6A5`6C5}6F5 6c616J636s656N676s696R6b1b0;6e6V6l040;6i4K6q5{6X6o6)6w6+6$6u6.6B4:0;6z6?6G6^6E6{6K6X6I6 6O3K0;6M736S756Q786W6$6U7c6#0L6Z7g5-1b0L6(2+390t2+2~2.0R2=3G0Q2b2K0^1$1R7q3b3s3Y057y0_7F5=0/1b3w7H6*0D3o7Q6/0m0Q1b0J0m180t0(7U5=1a040z3)0l7.0l6k1 7N040_0h7(5`7S3L7`3G0h0s1b0d0d332U837~3,7*0u88490P7*0b0t0X7_4R7;167*0K7,4Y7/8r7:6*0b2q04010y0(0@1|0g1t2x7#0(0l0@0S3J0l0Y0l0.0@2P017-8s7.8l018e1b8g8i8c4n0N1b0%8$3j1b1:0b0C0t3Y8t6/8(040-8=8W7*0H0F3)068r8W7?7^8+1 7|7:8k6*0m0h1b1H0C0d0m0g0X968m1b8b9a6/8Y048!8j3e6*8n8p588U8V8u8w010j0m1#1F1|2T100`0l8F0E7$9N8/0l9i0X0l0N0g9T1s8S8q9A931b2!0C0g0(0m8{6*9r9t9l018^8*9p6B8-0E8/8;4R8?5=8^0-8`a08|1b8~90926*940t9u7G7R7T9`6G9d04330Q2!2J7!9 9v6/8a9?9;8haf3Da7048o8T8U8W8v1b010!0g0Saq8:0l120l0i3J0t9,0l2X0Q9M9O9Q2X8D9#9z9%9:8fay9?9^9?0m9|9~9/8@1ba53ca15`8}awa,8#aj3Ga/b24*a=8:9?7*8 4Y917/9(7@ae9?98a:al0_ao1C8Fasagau9na 8Za-b5499xaE8saG9D0G0E0s331G0+0l9K2R140E1`0tbJaQaS1{aVaXaZ7!9P8Ha$a;bAab6/7?0Eaz2*a|3Gaxb1ata28)a:9e8/9h9jb99naD9$9Abeac9)0|8ga@6B2K0A3J1G0J2Z3.b}049ob=5`aH8x0)00a!8H9f9T9ja(br7)1b0Kb%c2b)9e0~bqaA9w1b9y4tc1b(5=b:b,7L5`b4cj3#b7cEb-8Wa3c75`cNa.b@bx4wcUc$049_cSb6042R0#cg0ucybccL5`adcO8Wbjc(3jal7y0#9Pc?bu9sbwc.bycxcI4Bc1bCaI1B0m0i0N9P0l8D9NbY9Q8J8L8NaY0Cdp8Gcudea*7V1b350g0i0t0p0gcZb3a_dKc/7Z8Gc?c^a)aFc3040D1,1{dN4gdD9XdGdIc+c-cv6Gc*a66*8^0$a`3sb.3,c#d01 cRd,cT048.b8d{9m7+czdUdC04dEd(dJe39@c%dac)am7WapbpdRe6d^497?9*9,9.d/e8eadHec58bd9BcBbgc}ah7}ed80820d0t0Z87edavedd`eg2t7*0+d!ehdI2/cVcP3Gbzc0bB9CaI0V9f1|0X00ds1:0C0@aW1|0_0g0TdxbZ0bdz3PdfdVer9-eW2teRd~3,d}cFe8e1e!eo8%a_d?3Dfg8,04eY2!d*b^e09}e2ezc`3Gc|biaieS2F8104832!39eNfBe4cif98db0eEbsaCddf1dB5=cl01didkdmaQfG8A8g7!0p2VaW00do0N0P0B9MbWdwcpf01cf2eCf4eta{aG0p1bfPfV9D00dPbZ000lf$0@f(e?0l2m8H9?2T1b0?d79=edfb2*8Wa;fsa?edgj040,gi9DaacA7M1b95edc fJ2ufD830p0R0RfIfM4nePgIf8fccw04eVeu9{fn1qfpeOdc4l3G989%gv0RaI01f_59490bg/3L9A0!gN2U0E1s2`9Lf@dq8H8Ndofo1|cpg*3,g^3o9AfYdl8C1tew9Vha523Ghdg`8Ug;g=f{g!2!1f0X0{0Cf6d|dMgZc!fOfqedgsd3d5g(chdScJfUd-048:1xhB16cYhEd h8hHgIhJ2QhLgI8ahOdAe7gDdWdYffcX7|35hAhYc/hTc=goefgQfm9fb{9khMc@fSf`cKeBg!h|h#i03xgE2#ekareme(huhRhw9jhzidgVhRaniifuiefKh,fTh.c{9)0`eshV3HiDhxiqc_gCiCeDfzeGgIeIfE0d1f0PgPise$bteQhGhMgYf 9b1bh!hMb 5R2tg,aFg.g:g=aGg_c11n0g8/0(0|dwh7g$h9h48M9L1p0E0*0Q0Ehbg@i`hf2xfZhi9ZdF8he}7$jd4nhpc10o0@0m0f2!dnh10!0(2U0I2J180Qcd2P8H9Ke/2Q8Qf*g 1t2!djhhjyjnjJ2/0E2$bo7!9Tds18cOg?jqjfhrg;engriIipf*iGhXi)9qi$gIgpe#c/hKe!aBc@j/i*hS1Ch}j_b?8_iGgsi,j|h iYj h(k1cGhNk4eCdX2wj@h@0Nh_k9hRich~c,fri29UdRi7eAcKbfb+kcj;hyj?kyd+khd#04kBb|i5i.hPi9fw3,eqc5h=9b2KjAjCjEjYjHcfi5gzaI0M0#jNf+bFbM2TbPf_aBizi8i9j:k6hUkNfrbmivkkfQk3ilhQd iokLkuixeekzhIigbnaNl9gWlbdTe)f|iEf5h`kQlfiK5e0U7J7r1S3a1J7t1J0C7vlJ2:2,2a2c2.0pbP7s7C1Pj~49ap0d0h0p0/0t0d0I0c1b1B1D9I0 i71S3t1Q0yaZ0T7$jbaYgf7$jEe^bK1|l#bG1:1j9}9Q0pdG0QaP1H0l0s0@2h7z0 2l0@jbaT0 2X0v0kmi0m0%0l0Mj3j71{0 aNjP0m8Bmp2n0 1{bK0gf;0CbJ1sga2x7y7!jx8Fjxh8l:l=1d9j3t1:l?1RlDiT2`eNm*0l0zaWmhl 339J0Ee^e{9Wf:0`mk1sdw1#0h0h8Q8F0 8b1Ce9kt9N1F3J1Jn90KgY1Z1Jm%1dnl1Um)7ziT0S9g0d1Jm.m:0Rm=3lm@bKm_jLm}dw1Fm_iV2UaP0pmfmh0I7z9Rdwi~jYhT8FmKk?jBaUh5j70gm_2m14e@2x0l1j0S1gnWn80s040S2!f*9Q2h2nnfn?nhmZnk0Em$o37Inq830Sl(nulCnqm/m;8:nAh1jK00f/mM0lnHmK0PnKaQmgmi2Xcr1fnY9PaV9X8I8K9Vdu8hn%gf1~n+1tn.n:j#n=n@n_og9Wcqndi4nggYnnm%o67K83hym-odnxnzbGoinDoknFonoHnJdwosnOnQowjXjZaN0l33n4nZaVoFj8oIn*dpn-0(n/o oPmA0 n|etoXo2o4npo$0d1{o)7Koenyogo-m^aPo:omooo@nLnNouh99Sp18Qoz8HoBe;j6aYp6n)0boKpapcn;05n9pfoTnc0gne0Upj0UoZo5m*830s9jpq7roep.hy191:e.py9MpA0goqo^nMotnPovdwpOoHpQpSoMaNmvhgdmdohkm|mM9_nn0Um#1d0U0_0{0}0b04.