Plus longues sous-suites communes

Considérons les deux « textes » "LAPIN" et "CAPRIN".

À quel point sont-ils proches ?

Pour répondre à cette question, on peut se demander quelle est la plus longue sous-suite commune à ces deux textes.

Définition

On appelle sous-suite d'une chaîne de caractères, une chaîne produite en enlevant zéro, un ou plusieurs caractères.

Par exemple, "AN" est une sous-suite de "LAPIN".

"AN' est aussi une sous-suite commune à "LAPIN" et "CAPRIN".

Dans certains cas, il peut y avoir plusieurs sous-suites communes de longueurs identiques. Par exemple les chaînes "abc" et "bac" admettent deux sous-suites communes de longueur 2 : "ac" et "bc".

On va donc plutôt calculer la longueur de la plus longue sous-suite commune aux deux textes.

La comparaison de "LAPIN" et "CAPRIN" donne ceci (sur fond vert les caractères "identiques", sur fond rouge les "différents") :

LAPIN

CAPRIN

La plus longue sous-suite commune est donc "APIN". Elle est de longueur 4.

Écrire la fonction lplssc (pour longueur plus longue sous-suite commune) qui prend en argument les deux textes à comparer (texte_a et texte_b) et renvoie la longueur de la plus longue sous-suite commune.

On propose deux versions de cette fonction : une version récursive utilisant la mémoïsation et une itérative.

Exemples
>>> lplssc("LAPIN", "CAPRIN")
4
>>> lplssc("abcd", "abcde")
4
>>> lplssc("aBaBaBaB", "aaa")
3
Aide

Une approche consiste à déterminer les longueurs des plus longues sous-suites communes de toutes les versions de chaque texte : la version à 0 caractère, la version à 1 caractère, etc. Il y a (1 + len(texte_a)) × (1 + len(texte_b)) cas à envisager.

En prenant encore une fois texte_a = "LAPIN" et texte_b = "CAPRIN", les différents cas envisagés apparaissent dans le tableau ci-dessous. On trouve dans chaque case la longueur de la plus longue sous-suite commune à chaque texte s'il s'arrêtait au caractère indiqué en début de ligne ou de colonne.

Ainsi, le 1 au bout de la double flèche est la longueur de la plus longue sous-suite commune aux textes "LA" et "CAPRI".

Tableau de longueurs

On constate que :

  • la première colonne et la première ligne du tableau ne contiennent que des 0. C'est en effet la longueur de la plus longue sous-suite commune dans le cas où l'un des textes est vide ;

  • si les derniers caractères considérés sont identiques, ce caractère commun fait partie de la sous-suite commune. On peut le supprimer et ajouter 1 au résultat de la case au dessus à gauche (flèche en diagonale);

  • si les derniers caractères considérés diffèrent, l'un des deux caractères (ou les deux) ne fait pas partie de la sous-suite commune. On compare les valeurs des cases de gauche et du dessus (flèches horizontale et verticale).

Version récursive

Cette fonction fait appel à la fonction récursive lplssc_rec qui prend en paramètres le nombre de caractères de chaque texte à comparer taille_a et taille_b. Cette fonction renvoie la longueur de la plus longue sous-suite commune aux taille_a premiers caractères de texte_a et aux taille_b premiers caractères de texte_b.

Par exemple, avec texte_a = "LAPIN" et texte_b = "CAPRIN", l'appel lplssc_rec(2, 5) renvoie la longueur de la plus longue sous-suite commune à "LA" et "CAPRI".

On gardera trace des résultats intermédiaires dans un dictionnaire longueurs qui, à chaque couple (taille_a, taille_b), associe la longueur de la plus longue sous-suite commune.

La fonction étant récursive, on débutera par l'appel prenant en compte tous les caractères de chaque texte.

###(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èufvy n7aïS1me(P24C:jtwi]D[hE)6Oo;bcdgx?/0làqpQ.r-,}=+k95R{é050P0s0A0n0C0V0b0k0O0V0n0b0b0)010A0C0Y010406050b0g0r0r0n0#0j040p0L0V0g140L0l0k020n0r0Y0M0k0.0s1e0#0X0g0s0b050T1b1d1f1h190Y041F1M051P0T1P1R1M190P0C0i0|0~10120G0C0Q0G0V1)0G0A17050@0N0V0s1!0 11011(1*1,1*0A1=1@1:0A0N0L0P1h1;0#1N0A0G0|1k0b0Y0n0l120v011_1$010h0_0s0l1s0s1:2h2j2o1{2r1@2u0r2w040a0k0u0#0L0Y0L0b0C1n1p0=2f0#0#0s0O2R1F2y0l1N0T2d2%0A2b2a2c0P2A121,0l2t2O1:1X1Z0}1`2;0C2?0l271Y1:0Y2W1N2#2%381a2i1p2|2p310#1e0V170k0q2!3c183b2z3e1{3g3i3k0v3n2j3p2#2:013u0n3j040k0c3y2$193B3s123E3G0k0w3K3A3c3C3Q3k0-3U3M3W3O3D0L3h3F3k0J3#3q3d1#3t3*3v3H0m3/3N3=3P3@3,3H0e3{3%3}3)3+3R0,433r453Y040q0U4a3;2}463^0q3m1G3o3$4b4j4d0q3x4o3z4q4i3f3 3G0q3J4w3L3:3X4B170q3T4F3V4r4A474K3!4N1O361F2`2*0P2.3C0O272G0;1Y1N350s373o3U054%0=4/4P1{0+170=0h4;3|4j0B3k4 444s0h170V0Y0`0b0O544_1216040t5e4z3t170A0s0R5o0d0n5k3C5h0%3U0k4H3(0l5n5p5r0N5u3(5h0I0y3#0k5N5z502p4{044}5H45523H5V56585a100O0d2W5d4U5Q1{5h5j5,553f5n0^0V1@5s5Z2p5w5y5A4c5@0_5`5G5;5f015J5L4N065O6d5P5=4`170C4~4N6f675C040@630s5{6l604j0L170)0)5 5-120r0C174g6u6C010L5X3*6B6g3P625_6s65386m5l126x046z6O676E6G5|5.176a386c6e6:6v5R172W0A0g0#0l6$6X016(046H6.6:5N6=6h046j6}5v175:3a6J6o6q6S6t7e6P68175x6I7l7g5^646*5g170I7a3(6L17310A7y457A786|7p6n581o0Q1C6`1E666~5h6-4p746e76125S797J6~7g5E6s5t7R7b040F7u3D6R5`7+6V7Y6K170$7E4j704n7k675h0D7}2p6Z6#7$3X5D5q6T7:5h7/7,5B7=8d897z7{851{7 8e170D7U4x7W7W7_6o0V7M7O0#7Q817S170F7d4:7f8j7j8K7l5~8l616p7s8k8F7-0I848R6w6y8o6D6F4e8%7`040*8+8z5$5c5)2X8r5i7:7r6r8N3z6W3C6Z7|8!2p8q8h458Q7^8L8T8|6U3o8 8m0492997l958W5I7w5M8w756J5S0s0`0s8^8u3L9q6;9a8A0l7N0s7P8^8I8`8M7@8O827n8/8M9d3z7_5J8Z9j67878/0N171e0R8^8J8v9A8x9C8;5(5*9)9K9b7i9M8~7_918+9l9N8G047o9X7%9R8^0Ia29e8y5#5b9:8@964j5/9?7h7?8^a89`9aaj8Va96J9|938p8)809 8X9p9,9r8P9o6b9-7l5S6^6`7Ia38a049D9F9Haf5}8H9*2$aa9@akaS6+a19QaYaq9T6J9V3#6/aC7KaO8B9G8D8+9Zau7v040/0(aA9f45aI0?aKa%59ac8?5+9m977c8`9#aO2t9=a!6Q6p7)8}aWa+7wam2$b04sbe2Dbhba4s8b5Fa67x6b1F4?4.4VbG0T4Y1F0A4!bL2,2(26282*0n1?bI4Y1L4^6~2W0r0d0h0n0+6s0G0c171x1z1B1D0k9y2%1V1Q040E2j0{0~0k0h1o2Y0C1o0k352 0O153F1^c54%1d2t0O1^2i0#0|0#0:0sck1@0k1Xc31o2u0C2W5zbFa;9E8C7Qcz0k2 2Q0Ccb2F0l0A0k0i0C2T1B0Cc6co2F210#0ncr1^051y040r0:0r0L0o0bco1Fc$0!060K1p0~0lch0k2t1b2Q1^1@0{0n0Y0Y9u0{cm0O7P6j0{2t0kc-cZ1e0l0P2jcMb;6Sc{0bcMb aP8CcZ0kb 5a0gb~a=dd0Ldx0$c}5o2f1d0g2?ddcS0V00cd1o2P0P0f2W060AdB5ob~b=1@cWb=2T0O0G0nb;0k5o8cb?cy4(aO9/b80t2D0td-5r0na7du2td`bl0N0IbCcE0S1O3p1M0x0LcfducY0bdB0b0$c1c_2RdncMd7d90i0s0%cF0Ven0k262S1^0P0:0N1mcoc61f0kdI0|0 dt0N0 0sc;0x001DcM0Cc9d eK0{dBdu00eJ0=0{0=0g0Rd,7)0{dJ4%cL0C2tcM0n0gd83d1f0n2YdSeP0kb|0l0{c`0O0 etc52W0l0i0Le?crcw2X5ocKcM4=4(3C1}1+1-1/bZ3C70724:0Tcz0!e8bYc?cN0:0#6jffc|0gc~0kd+cqf7d10k0:0A0:d,cX2QfUe!310l0!2JdBckchb c5de0=dg2T2Pee1!fUfm4@d`8U5setap0de3bEd;060leSdoeG0{350:c-cLeAb}eXcs2Rcvcxf^4.dra?cDd;fA1Se91icS0Og5dp1^fPet0_c0e_cM2+0^5of)0?dFcecj0^eg1p6ab_0g0V3p1,04f;d0cZ6{e?8DeKcXe 2Wf5dPcPfFgadAcLcF0=e=b;0bf91p2i101^e_e,f7g(0Af0g8d70:g?0AdbdpdN1p0n0zdWc!bFfo1-1 1.2x9kaw4;fyd;0ke_0kcm1b0V0@cM0M1FgV19gVgXb=h1e~h3g*fg0h0hf0cLg`fR6_1Xc d$9Gh0eLg9c90bg/cje#0:f!0O0:f$fD5ae~gdf4gfeVgh0^cxcqhwgShzeXdw0{0QcXdhgqhD1FgSgs0Z1Cevd+eg2QeXfPc{fc0C0b0n0Q0:etb 0icb6`ew0C1dh7cIfje@dddV0O0+cncrgecqggc40lgihhd;gmaRfzfBb`0Hezg!eF1,9GhRfbfdffiritckfNhccNe?g;0P002 h$2Wckdih?iJh^iLiN0ke!f*cqcRhSgGcr0:0z0Wc6hwe@ePiTbJ0?5^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èufvy n7aïS1me(P24C:jtwi]D[hE)6Oo;bcdgx?/0làqpQ.r-,}=+k95R{é050P0s0A0n0C0V0b0k0O0V0n0b0b0)010A0C0Y010406050b0g0r0r0n0#0j040p0L0V0g140L0l0k020n0r0Y0M0k0.0s1e0#0X0g0s0b050T1b1d1f1h190Y041F1M051P0T1P1R1M190P0C0i0|0~10120G0C0Q0G0V1)0G0A17050@0N0V0s1!0 11011(1*1,1*0A1=1@1:0A0N0L0P1h1;0#1N0A0G0|1k0b0Y0n0l120v011_1$010h0_0s0l1s0s1:2h2j2o1{2r1@2u0r2w040a0k0u0#0L0Y0L0b0C1n1p0=2f0#0#0s0O2R1F2y0l1N0T2d2%0A2b2a2c0P2A121,0l2t2O1:1X1Z0}1`2;0C2?0l271Y1:0Y2W1N2#2%381a2i1p2|2p310#1e0V170k0q2!3c183b2z3e1{3g3i3k0v3n2j3p2#2:013u0n3j040k0c3y2$193B3s123E3G0k0w3K3A3c3C3Q3k0-3U3M3W3O3D0L3h3F3k0J3#3q3d1#3t3*3v3H0m3/3N3=3P3@3,3H0e3{3%3}3)3+3R0,433r453Y040q0U4a3;2}463^0q3m1G3o3$4b4j4d0q3x4o3z4q4i3f3 3G0q3J4w3L3:3X4B170q3T4F3V4r4A474K3!4N1O361F2`2*0P2.3C0O272G0;1Y1N350s373o3U054%0=4/4P1{0+170=0h4;3|4j0B3k4 444s0h170V0Y0`0b0O544_1216040t5e4z3t170A0s0R5o0d0n5k3C5h0%3U0k4H3(0l5n5p5r0N5u3(5h0I0y3#0k5N5z502p4{044}5H45523H5V56585a100O0d2W5d4U5Q1{5h5j5,553f5n0^0V1@5s5Z2p5w5y5A4c5@0_5`5G5;5f015J5L4N065O6d5P5=4`170C4~4N6f675C040@630s5{6l604j0L170)0)5 5-120r0C174g6u6C010L5X3*6B6g3P625_6s65386m5l126x046z6O676E6G5|5.176a386c6e6:6v5R172W0A0g0#0l6$6X016(046H6.6:5N6=6h046j6}5v175:3a6J6o6q6S6t7e6P68175x6I7l7g5^646*5g170I7a3(6L17310A7y457A786|7p6n581o0Q1C6`1E666~5h6-4p746e76125S797J6~7g5E6s5t7R7b040F7u3D6R5`7+6V7Y6K170$7E4j704n7k675h0D7}2p6Z6#7$3X5D5q6T7:5h7/7,5B7=8d897z7{851{7 8e170D7U4x7W7W7_6o0V7M7O0#7Q817S170F7d4:7f8j7j8K7l5~8l616p7s8k8F7-0I848R6w6y8o6D6F4e8%7`040*8+8z5$5c5)2X8r5i7:7r6r8N3z6W3C6Z7|8!2p8q8h458Q7^8L8T8|6U3o8 8m0492997l958W5I7w5M8w756J5S0s0`0s8^8u3L9q6;9a8A0l7N0s7P8^8I8`8M7@8O827n8/8M9d3z7_5J8Z9j67878/0N171e0R8^8J8v9A8x9C8;5(5*9)9K9b7i9M8~7_918+9l9N8G047o9X7%9R8^0Ia29e8y5#5b9:8@964j5/9?7h7?8^a89`9aaj8Va96J9|938p8)809 8X9p9,9r8P9o6b9-7l5S6^6`7Ia38a049D9F9Haf5}8H9*2$aa9@akaS6+a19QaYaq9T6J9V3#6/aC7KaO8B9G8D8+9Zau7v040/0(aA9f45aI0?aKa%59ac8?5+9m977c8`9#aO2t9=a!6Q6p7)8}aWa+7wam2$b04sbe2Dbhba4s8b5Fa67x6b1F4?4.4VbG0T4Y1F0A4!bL2,2(26282*0n1?bI4Y1L4^6~2W0r0d0h0n0+6s0G0c171x1z1B1D0k9y2%1V1Q040E2j0{0~0k0h1o2Y0C1o0k352 0O153F1^c54%1d2t0O1^2i0#0|0#0:0sck1@0k1Xc31o2u0C2W5zbFa;9E8C7Qcz0k2 2Q0Ccb2F0l0A0k0i0C2T1B0Cc6co2F210#0ncr1^051y040r0:0r0L0o0bco1Fc$0!060K1p0~0lch0k2t1b2Q1^1@0{0n0Y0Y9u0{cm0O7P6j0{2t0kc-cZ1e0l0P2jcMb;6Sc{0bcMb aP8CcZ0kb 5a0gb~a=dd0Ldx0$c}5o2f1d0g2?ddcS0V00cd1o2P0P0f2W060AdB5ob~b=1@cWb=2T0O0G0nb;0k5o8cb?cy4(aO9/b80t2D0td-5r0na7du2td`bl0N0IbCcE0S1O3p1M0x0LcfducY0bdB0b0$c1c_2RdncMd7d90i0s0%cF0Ven0k262S1^0P0:0N1mcoc61f0kdI0|0 dt0N0 0sc;0x001DcM0Cc9d eK0{dBdu00eJ0=0{0=0g0Rd,7)0{dJ4%cL0C2tcM0n0gd83d1f0n2YdSeP0kb|0l0{c`0O0 etc52W0l0i0Le?crcw2X5ocKcM4=4(3C1}1+1-1/bZ3C70724:0Tcz0!e8bYc?cN0:0#6jffc|0gc~0kd+cqf7d10k0:0A0:d,cX2QfUe!310l0!2JdBckchb c5de0=dg2T2Pee1!fUfm4@d`8U5setap0de3bEd;060leSdoeG0{350:c-cLeAb}eXcs2Rcvcxf^4.dra?cDd;fA1Se91icS0Og5dp1^fPet0_c0e_cM2+0^5of)0?dFcecj0^eg1p6ab_0g0V3p1,04f;d0cZ6{e?8DeKcXe 2Wf5dPcPfFgadAcLcF0=e=b;0bf91p2i101^e_e,f7g(0Af0g8d70:g?0AdbdpdN1p0n0zdWc!bFfo1-1 1.2x9kaw4;fyd;0ke_0kcm1b0V0@cM0M1FgV19gVgXb=h1e~h3g*fg0h0hf0cLg`fR6_1Xc d$9Gh0eLg9c90bg/cje#0:f!0O0:f$fD5ae~gdf4gfeVgh0^cxcqhwgShzeXdw0{0QcXdhgqhD1FgSgs0Z1Cevd+eg2QeXfPc{fc0C0b0n0Q0:etb 0icb6`ew0C1dh7cIfje@dddV0O0+cncrgecqggc40lgihhd;gmaRfzfBb`0Hezg!eF1,9GhRfbfdffiritckfNhccNe?g;0P002 h$2Wckdih?iJh^iLiN0ke!f*cqcRhSgGcr0:0z0Wc6hwe@ePiTbJ0?5^0b04.
Version itérative

Dans cette version itérative on détermine là encore les longueurs des plus longues sous-suites communes de toutes les versions de chaque texte.

On peut toutefois remarquer que les deux formules de récurrences (derniers caractères identiques ou différents) ne font intervenir que deux lignes à la fois. On peut donc compléter le tableau ligne par ligne en partant de la première et en ne gardant trace que de la dernière ligne complétée.

Une seule ligne est nécessaire

###(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èufvy n7aêS1me(P24C:twi][h)6Oo;bcdg/0làqp.rL-,=+k95Rxé050M0s0z0n0B0Q0b0k0L0Q0n0b0b0Z010z0B0T010406050b0g0r0r0n0V0j040p0I0Q0g0~0I0l0k020n0r0T0J0k0(0s180V0S0g0s0b050O1517191b130T041z1G051J0O1J1L1G130M0B0i0?0^0`0|0E0B0N0E0Q1Z0E0z11050.0K0Q0s1U0_0{011Y1!1$1!0z1,1.1*0z0K0I0M1b1+0V1H0z0E0?1e0b0T0n0l0|0v011:1W010h0:0s0l1m0s1*2b2d2i1=2l1.2o0r2q040a0k0u0V0I0T0I0b0B1h1j0,290V0V0s0L2L1z2s0l1H0O272X0z2524260M2u0|1$0l2n2I1*1R1T0@1;2+0B2-0l211S1*0T2Q1H2V2X32142c1j2?2j2{0V180Q110k0q2U3612352t381=3a3c3e0v3h2d3j2V2*013o0n3d040k0c3s2W133v3m0|3y3A0k0w3E3u363w3K3e0%3O3G3Q3I3x0I3b3z3e0G3V3k371V3n3!3p3B0m3)3H3,3J3.3$3B0e3=3X3@3Z3#3L0$3}3l3 3S040q0P443+2@403/0q3g1A3i1I301z2;2!0M2(3w0L212A0+1S1H2 0s314j4i3t054s0,4A454d0#110,0h3O3*3w0A3e4O3?4d0l0h110Q0T0;0b0L4T3~4d10040t4(4I39110z0s0)4=0d0n4.4c2j4+0Y3O0k4P3Y0l4;4?4^0K4{3w4+0F0y3V0k5f514U4:040Q1i0N1w0g0V1y4C2W5h4)2j0I110Z50523 4+0D593Y0r0B114a5s3B5B4J110h3!5A5i3n110d5S5v1=0I4R042_5X4/3n0K110V2d0N0s5F5C114-5L5N395+5k2n5;4*5?5~5j4=4@0s4_611=5b5(4|5Z110!6a3w5H114h345T0|5b0C5e5g5_1=4K045Q0V6f534;0/0Q1.0d585L5u5)0|5!115%6F6r3J5{5-0l5/676m605^6l016h486T014~6x465{2x6#4+5@6k5Y3J55646D6,110F6(4d5x046e6M6X6Z6j4j6X5b5d5L065g7a6G6b6;044=1n6{5w5y7i68115E6W6:6Y5I045K327c3w6t6v7l7e5W707q6J5$0l7A3x6P5.5:7p6H6$6V6/7O0l6*5}7N7d7P4,6#547f56654`7W5a6_7I6}6 7v6N7r6i6^040F6o787b6q6X7y5R7D7S6z0:6C7)7:6X7F6L877q7T5,7L7@6.747q727@4 817X8d5|7H7*3Y6-7!6=4^868i7O698n3w7.7I8k8s5=7^7732797|7b7;6t0B4N8C6y7$6?8y4D757n8v7f6A857-110X8F7s738Y7q4+7`8b7O6}0Z5z8T468w656E7R7X5D8#0.848~8)048+8{4d8G907+040C8K3i8M8N8N7;7#7g0T7@7o9d8U946B7(7@8=3i7w3Y8^8,7?9a7j6~7I7#5l6R5o5q9q938%9w9F6c989D6!8H5 9f6p9k5f8P110s0;7M9s8I9h3t9j9#7a9m557h9X4}8!9_5U8$95669|6U9Z9S6I7ka47J11180)8g931s9pa17Y9r8z8o839va08?7X6}99ao6g8-9x8mas8U9K5n0s5p5r9,9Yai8/829~am8X2W7;8;6`7{9l6X9J5m9MaD9z7;9Ca79nae9!9A3 6t2Q0z5p8rax8|5kaUaB9Nag92ag8p6+a^7Qaj3R8}ana 8t6_9y9/1z4F4z4kba0O4n1z0z4pbf2$2Y20222!0n1-bc4n1F4H7X2Q0r0d0h0n0#650E0c111r1t1v1x0k9.aM1M3j1G0x0-4=0k5Q0l2S0B1i0k1x0z0k2K0*5-0~0i1/0-290l0b2#0g2K1/0n1g0I5p0k0M000g2-0k200g0@1/4E4t3w1@1#1%1)bt7x5P80340Ob9040U1IbN040W1/1|0sb@0kb/0I0L0#2db!1.0=azaVb{bI1R0h0hb%2n4=0=0bb_0b0X15b=0=4s17b~cF0s0i5-2K0k0n0i0I0B0V51b9c71%1_1(2r8jaua78Ea!7Ua.b38I8haHak8V8x7@aPcgci299K2-0=b,c52N3Yc8c:cb7;9caX886d9Ic{aca`b18 c}9Yd54Bd71_da0U060H371ib/0nbR0l0*2d0rc)b.0kbH0kcAbS3.0gdS2N0V0*0L5p2QbU1/b bTb!0n0T0T9)0=1v000RcE0=0i3za?0=0B0`1w0=2N0^0k0r0o2zdR1Zb b_cEdR0n0k2 dZ0*0,0l4=ckbMbsdDeeaBb!0M1i0Lct1/4sejcK0sc+b|1g0:d}eAcE0g0)0kcqb@eJ2Nddew3 dgcac=7Odk4Dch4t3Bdz0sel1P1Kcned4y5H0f2Qe70Nb 0M0geKbo1.csb,e2e,0Be.ew1e1ib b ex0~2n2`b!dQ0,0=ePc.1^eTcc5G7s7udxeZe%cm0ub_c+cU4!0*4=c+dSb@2#bI0L0_1x0Y0kbXeD1$0b1/dS6v0rdVcX0kdYd!2P2n0Le$cl13bd0-6A0b04.

###(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èufvy n7aêS1me(P24C:twi][h)6Oo;bcdg/0làqp.rL-,=+k95Rxé050M0s0z0n0B0Q0b0k0L0Q0n0b0b0Z010z0B0T010406050b0g0r0r0n0V0j040p0I0Q0g0~0I0l0k020n0r0T0J0k0(0s180V0S0g0s0b050O1517191b130T041z1G051J0O1J1L1G130M0B0i0?0^0`0|0E0B0N0E0Q1Z0E0z11050.0K0Q0s1U0_0{011Y1!1$1!0z1,1.1*0z0K0I0M1b1+0V1H0z0E0?1e0b0T0n0l0|0v011:1W010h0:0s0l1m0s1*2b2d2i1=2l1.2o0r2q040a0k0u0V0I0T0I0b0B1h1j0,290V0V0s0L2L1z2s0l1H0O272X0z2524260M2u0|1$0l2n2I1*1R1T0@1;2+0B2-0l211S1*0T2Q1H2V2X32142c1j2?2j2{0V180Q110k0q2U3612352t381=3a3c3e0v3h2d3j2V2*013o0n3d040k0c3s2W133v3m0|3y3A0k0w3E3u363w3K3e0%3O3G3Q3I3x0I3b3z3e0G3V3k371V3n3!3p3B0m3)3H3,3J3.3$3B0e3=3X3@3Z3#3L0$3}3l3 3S040q0P443+2@403/0q3g1A3i1I301z2;2!0M2(3w0L212A0+1S1H2 0s314j4i3t054s0,4A454d0#110,0h3O3*3w0A3e4O3?4d0l0h110Q0T0;0b0L4T3~4d10040t4(4I39110z0s0)4=0d0n4.4c2j4+0Y3O0k4P3Y0l4;4?4^0K4{3w4+0F0y3V0k5f514U4:040Q1i0N1w0g0V1y4C2W5h4)2j0I110Z50523 4+0D593Y0r0B114a5s3B5B4J110h3!5A5i3n110d5S5v1=0I4R042_5X4/3n0K110V2d0N0s5F5C114-5L5N395+5k2n5;4*5?5~5j4=4@0s4_611=5b5(4|5Z110!6a3w5H114h345T0|5b0C5e5g5_1=4K045Q0V6f534;0/0Q1.0d585L5u5)0|5!115%6F6r3J5{5-0l5/676m605^6l016h486T014~6x465{2x6#4+5@6k5Y3J55646D6,110F6(4d5x046e6M6X6Z6j4j6X5b5d5L065g7a6G6b6;044=1n6{5w5y7i68115E6W6:6Y5I045K327c3w6t6v7l7e5W707q6J5$0l7A3x6P5.5:7p6H6$6V6/7O0l6*5}7N7d7P4,6#547f56654`7W5a6_7I6}6 7v6N7r6i6^040F6o787b6q6X7y5R7D7S6z0:6C7)7:6X7F6L877q7T5,7L7@6.747q727@4 817X8d5|7H7*3Y6-7!6=4^868i7O698n3w7.7I8k8s5=7^7732797|7b7;6t0B4N8C6y7$6?8y4D757n8v7f6A857-110X8F7s738Y7q4+7`8b7O6}0Z5z8T468w656E7R7X5D8#0.848~8)048+8{4d8G907+040C8K3i8M8N8N7;7#7g0T7@7o9d8U946B7(7@8=3i7w3Y8^8,7?9a7j6~7I7#5l6R5o5q9q938%9w9F6c989D6!8H5 9f6p9k5f8P110s0;7M9s8I9h3t9j9#7a9m557h9X4}8!9_5U8$95669|6U9Z9S6I7ka47J11180)8g931s9pa17Y9r8z8o839va08?7X6}99ao6g8-9x8mas8U9K5n0s5p5r9,9Yai8/829~am8X2W7;8;6`7{9l6X9J5m9MaD9z7;9Ca79nae9!9A3 6t2Q0z5p8rax8|5kaUaB9Nag92ag8p6+a^7Qaj3R8}ana 8t6_9y9/1z4F4z4kba0O4n1z0z4pbf2$2Y20222!0n1-bc4n1F4H7X2Q0r0d0h0n0#650E0c111r1t1v1x0k9.aM1M3j1G0x0-4=0k5Q0l2S0B1i0k1x0z0k2K0*5-0~0i1/0-290l0b2#0g2K1/0n1g0I5p0k0M000g2-0k200g0@1/4E4t3w1@1#1%1)bt7x5P80340Ob9040U1IbN040W1/1|0sb@0kb/0I0L0#2db!1.0=azaVb{bI1R0h0hb%2n4=0=0bb_0b0X15b=0=4s17b~cF0s0i5-2K0k0n0i0I0B0V51b9c71%1_1(2r8jaua78Ea!7Ua.b38I8haHak8V8x7@aPcgci299K2-0=b,c52N3Yc8c:cb7;9caX886d9Ic{aca`b18 c}9Yd54Bd71_da0U060H371ib/0nbR0l0*2d0rc)b.0kbH0kcAbS3.0gdS2N0V0*0L5p2QbU1/b bTb!0n0T0T9)0=1v000RcE0=0i3za?0=0B0`1w0=2N0^0k0r0o2zdR1Zb b_cEdR0n0k2 dZ0*0,0l4=ckbMbsdDeeaBb!0M1i0Lct1/4sejcK0sc+b|1g0:d}eAcE0g0)0kcqb@eJ2Nddew3 dgcac=7Odk4Dch4t3Bdz0sel1P1Kcned4y5H0f2Qe70Nb 0M0geKbo1.csb,e2e,0Be.ew1e1ib b ex0~2n2`b!dQ0,0=ePc.1^eTcc5G7s7udxeZe%cm0ub_c+cU4!0*4=c+dSb@2#bI0L0_1x0Y0kbXeD1$0b1/dS6v0rdVcX0kdYd!2P2n0Le$cl13bd0-6A0b04.