Un robot nettoyeur
Dans ce problème, on cherche à résoudre le plan de trajet pour un robot mobile qui nettoie le sol d'une pièce rectangulaire avec des meubles, des murs, des obstacles.
Présentation
Le sol de la pièce est pavé de carreaux carrés dont la taille convient au robot nettoyeur (1 × 1). Il y a des carreaux propres et des carreaux sales, et le robot peut transformer un carreau sale en carreau propre en visitant ce carreau.
Il peut également y avoir des obstacles (meubles...) dont la taille correspond à celle d'un carreau. Si un obstacle est sur un carreau, le robot ne peut pas le visiter. Le robot se déplace vers un carreau adjacent avec un seul mouvement. Le carreau sur lequel le robot se déplace doit être l'un des quatre carreaux adjacents (c'est-à-dire est, ouest, nord ou sud). Le robot peut visiter un carreau plusieurs fois.
Objectif
Il s'agit d'un problème d'optimisation pour lequel on cherche le trajet qui passe sur tous les carreaux sales en un minimum de mouvements.
Un pièce à nettoyer est représentée par une matrice de caractères :
o pour le robot
x pour un obstacle
* pour un carreau sale
. pour un carreau propre.
Exemple d'entrées
| Python |
|---|
| 7 5
.......
.o...*.
.......
.*...*.
.......
15 13
.......x.......
...o...x....*..
.......x.......
.......x.......
.......x.......
...............
xxxxx.....xxxxx
...............
.......x.......
.......x.......
.......x.......
..*....x....*..
.......x.......
10 10
..........
..o.......
..........
..........
..........
.....xxxxx
.....x....
.....x.*..
.....x....
.....x....
|
Sortie attendue
Le nombre de mouvement minimal, ou -1 si un des carreaux n'est pas accessible.
Avant d'avoir une approche exhaustive, on peut chercher une première solution approximant le minimum par une stratégie gloutonne.
Trouver si un obstacle est présent sur le chemin le plus direct entre deux carreaux.
| Python |
|---|
| def sans_obstacle(d:(int,int), a:(int,int), liste_obstacles)->bool:
"""
Renvoie True si le chemin de d vers a ne croise pas d'obstacle
Les chemins possibles sont soit
- horizontal puis vertical
- vertical puis horizontal
"""
ld,cd = d # ligne et colonne départ
la, ca = a # ligne et colonne arrivée
obstacle = False
# Test d'abord déplacement horizontal puis vertical (chemin 1)
for o in liste_obstacles:
lo, co = o # ligne et colonne obstacle
# test sur la ligne horizontale depuis le point de départ
if lo == ld and min(cd,ca) <= co <= max(cd, ca):
obstacle = True # obstacle rencontré sur le déplacement horizontal
# test sur la ligne verticale qui va au point d'arrivé
if co == ca and min(ld,la) <= lo <= max(ld, la):
obstacle = True # obstacle rencontré sur le déplacement horizontal
# test si aucun obstacle rencontré sur le chemin 1
if not obstacle:
return True
|
Plusieurs solutions on été proposées :
- chercher un carreau sale le plus proche possible atteignable directement sans obstacle, (cette situation n'existe pas toujours)
- déplacer le robot au minimum pour qu'il se retrouve sur un carreau permettant d'accéder un carreau sale le plus proche possible sans obstacle...
Et un parcours en largeur (BFS)
Et si, en partant de la position du robot, on cherchait à l'aide d'un parcours en largeur la distance de tous les carreaux atteignables de la pièce
.128013oèPf 8lkg5:j+,bry2a1éh3tvw!=u6e[(*Sn9]x_s-c)7iqm./4p0d050$0F0y0t0U0h0P0f0R0h0t0P0P0C010y0U0!010406050P0D0W0W0t0q0r040J0b0h0D0`0b0K050Y111315170 0!04051n1g1q0Y1n0 0$0U0z0/0;0?0^0;0K0j0D0t0j0F0Q0!0r0y0w1e0f0w0U0j0w0h1S0w0y0}050*0p0h0F1z0=0@011R1T1V1T0y1#1%1Z0y0q1o1N0/1a0P0!0t0K0^0s011)1B010e0,0F0K0t0W0F1Z1~20251+281%2b2d0}0a0f0d0q0b0!0b0P0U1d0K0f0(1|0q0q0F0R2y1g2g0K1o0Y1N2L1^1`1_1!0$2i1C0U0K2a2v1Z1w1y0:1*2V2X0K0b2#1Z0!2E1o2J2L2=101 2z2%262+0q140h1Z0t1Q2E0e0^030O0O0R2,0F1V2*0b0Q0s0Q0u0}0f0u1g0t2?2_0~2^2h2{1+2}2 31330F350137393b3d2Y3g3g3k0s3n3p203r2J2U013w0t301o320w3436383a0(3G2+3I0x3k0x3M2I3q0 3Q3u0^3T3V053X3Z3C3#3F2W3H3h0Z3k0Z3.1h3:3s2`1A3v0b2~3U3y3Y3A3!3E3%403)3h0k3k0k462=3;2_3R3^4g3|3D3$3c4m3f3h0E3k0E4s483=4b3@4d3x3W3z3B4A3 3e3I0T3k0T4J3O4u3t4M3S4O4f4Q4h4S3~4l4V3h0g3k0g4!2K4$4a2(4)4e3_3{4i3}4k4C4;0Q0L3k0L4_3P4v3?4~4P3`4R4j4B3(4E3i0#0}0u0#5b4{4w4*505i535k4D3I0u3j045C5s495u4 4y524T4:413i235E3L0Y3o3/4#5H5e4x4,4z4/555O0u3+5E3-5T3N4`5X4(5Z5h4-5j4U5(435E455-5V5/4L4}5=514.545l5B4p5E4r5~475W612|5v5K655z560u4G5E4I6c4t5:626h5!5L5$673h0u4X5E4Z6q4K5d5;6u5?5#665A6z4?5E4^6E6e6G6t5J6v6j5_4n3i585E5a6R606T6g6V6J6w6L560s5o046;5G6f4c6,645^5N6Z0s5D706^6*6`5g6|5y6Y5m0s5Q7b734%6U765x5M5%6 5*0s5,5U6d6)7f6+7h5@786~7a5{0s5}7p6r6_4N6{7i6x6M3g690s6b7C6F7s754+6-6X7x3I0s6n7X7e4|7t7S777j6y3g6B0s6D7O6S7Q7F7u6K6k5O0s6O7`7!5I7?6.7^6 6#0s6%7/7r7#7R5w7v7)7J0x6=8e7}5Y6I7(7I560x5D8n8h6H7G8b8l5O0x5Q8w8q7g7%7H6/8v5*0x7o5.5c7;5f8B8t8D6Z0x5{8Q8z7$8a7@793*690x7N8I5t8i8s8W7V3h0x6n8-8T896i6}7k5m0x6B8_8:7=8M8*8@3*6O0x6Q868J888}8V808X8,6#0x858$6s8U8=7w90426=0Z5r6(967~8~9a8+0Q0Z5D9x8|8L997U9l9w5Q0Z5S958%8r7 9D7*0Z5*9P9A638C815m0Z5{9X9S8j9U9b9w690Z8#5 9r8(9M8?9O6n0Z6p9J9h8;6W9:7J0Z6B9~5b1r2:1g2#2O0$1`2T5e4B2!1x1o2/0F2;3q9,054Bah2h0U0$0^382J5B3yaoaq8O5m3j0f2m0Faw9Vat2L5U7E3S0}0!0U2F0FajaI0b0}0C9,0f9_0^0P5Q01a!0Xa$a%0X0Na(a%9,0 7qam2zav01ar2_7Wauapa?axa_aA2caCa|aE3h5Q3.aIaY0}a%0ba%a*a%0Ia$a-aP4va=a@203*a`aD9%3+a 2dbp9v5*b674aX5Qa+a$bda+bha/5Hbk0Oas42bob29%43bsb18u6Z5{bx8Kb804bBa)bZbF2@3QbIbK0Q695hbIb3b+24aBbu9Eb,5~b7bAbBbDa(b$aib(a{bl0K3I6nb-c2a}4Fb;b0b?7*c6b_by01bXbZckb 3ObHc8b*6Bc7cd7J4XbQct56crcgbW5Q0NcDcDa+cEcDcm2Kcoawb*6OcsbN9v4?cwcQ9EcOcA97cib{ckbEa/a.b%bjcpa^3h6#cPbS5m58cTc:3Ic.cX3Rcjb|b#c%bianc+bm6z6=c/c95ncbbtcU7*5q1Zc`5ec|cGc~6rbGc1cMc,3i5Dd6b/5Cd9bRd7dtaGa:c{c!a(b}a,c dlc*dnd35PbMc@6z23c?dwb5df4(c|bfbca(dVcJdzb)do5)dLdwbrb=db7Jd%dyaWcZb9c}bBa!01dZcLa|b*0ubU32b.9%d~ducx5`deaHch0KaKaM0RaOa/aVaQaSaUd:ea04aLaNd0cYaRbYep4w0}1~1V0yet5e0|040HezdT5D00eE4}0P2e04091fdGbWeGeI26eB0Sd`dmd|d$b,e0c8ds4pdPe%e73rePa;d2c46zc6e#e56Z6me4d,6lcfe88K0i0}0(0eeS1+0A3kf43@0eaK2v0O2s0p0beye-3ReBeDfi5Yebeofm4(eU0leWdHeYdJ6Ad(dscvd+dM3icz3o0ffHegchf0040e4dejaIel0hfPch0bf6042WfT8K0K0p0}0q201If801fkf+f#0}2lf+f-fq62foedf=0}0S0SftdFc)d1dIe:3icOe?e{5(cSfCdwcWfGfIgfd:fLfN0qfZcYel0Rgl3RfV0}fYefekf$04f(1Eeeg1cYf?gB4wgwf;f@eT0}flgEfnemecgAc0cheB0Gf+0W0U0}9pgMfr0}0Mf}f dkgEd#fxc.g7fD0uc=gbdsc_gegfg`fJe gsf3gufQf_gQcnaIgTf.f:f{040MgUgI3v0}gohd0^eB0Mgp5eer0CaTh0ch0PeG0beHhhf,0}g)48fig,g46;fz9%hEe)hGd55-g{hMfIghf%0)0D0qeO2=g|gCgKh704fShweB0ohZhgg!4}eUfug2fwhDdqg/d770e`fDh^dyc(gRh/c37Wb5h?b/7bh_h@dRe~cYfLf2f+fWaVhw0Kfa040p0e0Ph9gLh~gmf10F1 0qfhh+gJ04h(hqf!h2h9f~h.e.g37Wbwi3hGd*ccg87le+d:iehOhw0P0$0}d^d_g0ip0fhC7Wd i$e$hGbPg?i,iQb7iW04gf2E0y0bhS2X0f0;2A0U0P0*0Ked2A1(i_1c0F0.1%0.0R152E0t0D0N0f0t1;0F1S2b1$j92A200.0Di|141^0Uj4jgji1w2d0K2w1e0.2Bi~aL0cf`i!h4fvi0b4e!i*e@7ae(i.9v7Mi:hri=gfd^iFjTh:7We=j*h`4GhIjYe}i?hOaI0iel0e2s0Widf7iggn1a1%2G0UjGj i?f+j`gs0W2uiuhl5;ir0V0Dh35/hBe/7WcriKjYfBiNh`fFj@fHek0}2kklk9eh04hphVkz040(kjkCd:fkeVjNcKeXjQ3gg6j.h@gakukXe+ggh1040wkg4}hnk*2|gG2ainhZenjMiw1+h-kQd!kob4g.kWi4g=kZl1k#j^e9h8iAeqeil9gFf:k:h$hYigiClg04hck^0^gWgYh9g%j)i%8,d5kr9E8ei6b/lzdyk$l7kJj0j2edimlchmlbkHh50}0Glm3qhWgq0}0QgVgX5Ek-1+gifOlLkh040Ol#0^grfXhUlTgvf%f)kMlPeChZh#lnhx040Shkl)4}l%gkm32|0}l,m71+l/gtlOe9gwgyf*lkiojOiBh!iDm2g*i#lu0Q8nhFbvazjXlydqhLl6mn0rm6l~h%l-aJ040NmGl=kEkGmOlF0(itivhAg+k}mui2l0bqdOmz7*8wl5kyk%1wj120lJh9lSmmiq04mFlrm?kRlFmMlrmJk,mblolZgZmWmsmY8GmwlyiMdafDnah|etmt8Qnbm)i-l3bqbUmCm,fKirg l~ief.iiik0Pfd2Fk;li04jd2D0FjgiDhz5WkniH8,jSe1bvjWnonTm+g`hPfXnvmRf!k/l;m@fjlhl~j{29nLltn9j-nSlyj:m(8dj?hNlEmn0t2Gkkl}n$lakFmJn.1%f+er0Xk=2t1%0emVn*eAgKkPmrn*njkqm#bvktned78_nXhNkI0r0th9izmfmn0NoAn301n2oDm^o00yo2n;nPmukVn@m)kYotlBgdkxn}nZgjo7f10NoBo%kJ0rn1fWmeo4n+llmlm}8Klp04n6oig#iyoalWlY5piDoCo;ojl{hwo`3mlkp5o}4}o`o|o^hXm0pd2KlUp7o@dz5epgo*p9lZpbmHf|plkDgSn,i#lM04lXpup3pcp2o{mpnMpmd:0R5D030f2E0R0w0F0qpV1(0(jcjenJjhjj0$0mo02a0ylKompikWb*9enl8dl2oWbqg^oZn}mDm^0r0zptoKeumLq4oHoJp6o~ppoyoGq6pE0no+0$o-pJoHeloFn10}qjqoo(iDaUh}onmY9op_56qBj;9EqBlDq0nYj_g~o+q3o.gsn)pOfQmhl^nEn-0}k)lkolqck+fW200$o+0Nq9qh4(mdqRpAn%l@gzqWpDl*o3peixq#3Opnq/q(0Kq*qugOfppxllhZqOlkhbhZq,n0qa0}0BmQr0d:hs0}000Nhvq.q%0}q)qklHm:j9m=rbq-q`h,g$m|pql*rgrdqrkFrlqSfUp1pHl!lkpNq=cYpQ0}pS0z0bj02W0.2+2z2a3a2E2A0v3a0D0zpXohkmmXoQ9xqC5Or|qF9OmBg_qJg{kIkBp0esnF0t0!0!2ar5r90Hqek%rcr9pzkIrKr9f}oPj+42m!oT9}m%nVqGi8p s4q1q7m.lIrAlkrHoyrDq}k_rGrfsLp=p7mqq$26qbrmm-ryj3sHr9sJsjqgrEixrenFqqrLri04qtrt26pamJrY04pS01edpYjb243aed0KjxkLjHjqnHjfp)0tp+p-t4p:n7qzr{iJoqqGnddvb/9PowhMkInAnCh*s*sNp8qXfMn/q!aUfIqyp=mt9Xr}bTnnp|9vtJnhnOss9(tK9WnUtNqGb^s3s6tCl~obhZsbsdr4q_sM3@irmUqwk{d{kT9?tU3It_s09}n|sDgNtupUt-sRl*s7tDt?kSbJdo9~t`42ostobOkwn~iahQoNhTrxm/s!tgnN2@0Yala2aga4ad1g0ya7uB2R2M0tjp2La5a.0(0*0,0P04.
Résolution exhaustive
Voici une solution qui teste tous les trajets possibles en permutant l'ordre des poussières...
.128013oP;f 8lkg5:j+,bry2a1}h3tvw=u6{e[(*Sn9]x_s-c)7im./4p0Od050$0F0y0t0U0h0P0f0R0h0t0P0P0B010y0U0Z010406050P0C0V0V0t0q0r040J0b0h0C0`0b0K050X111315170 0Z04051n1g1q0X1n0 0$0U0z0/0;0?0^0;0K0j0C0t0j0F0Q0Z0r0y0w1e0f0w0U0j0w0h1S0w0y0}050*0p0h0F1z0=0@011R1T1V1T0y1#1%1Z0y0q1o1N0/1a0P0Z0t0K0^0s011)1B010e0,0F0K0t0V0F1Z1~20251+281%2b2d0}0a0f0c0q0b0Z0b0P0U1d0K0f0(1|0q0q0F0R2y1g2g0K1o0X1N2L1^1`1_1!0$2i1C0U0K2a2v1Z1w1y0:1*2V2X0K0b2#1Z0Z2E1o2J2L2=101 2z2%262+0q140h1Z0t1Q2E0e0^030O0O0R2,0F1V2*0b0Q0x0Q0u0}0f0u1g0t2?2_0~2^2h2{1+2}2 31330F350137393b3d2Y3g0Q23040f0s3n3p203r2J2U013w0t301o320w3436383a0(3G2+3I0x3k0x3O2I3q0 3S3u0^3V3X053Z3#3C3%3F2W3H3h0Y3k0Y3:1h3=3s2`1A3v0b2~3W3y3!3A3$3E3)423+3h0k3k0k482=3?2_3T3`4i3~3D3(3c4o3f3h0D3k0D4u4a3@4d3_4f3x3Y3z3B4C413e3I0T3k0T4L3Q4w3t4O3U4Q4h4S4j4U404n4X3h0g3k0g4$2K4(4c2(4+4g3{3}4k3 4m4E4?0Q0L3k0L4{3R4x3^504R3|4T4l4D3*4G3i0!0}0u0!5d4}4y4,525k555m4F3I0u3j045E5u4b5w514A544V4=433i3K0u3N0X3o3;4%5J5g4z4.4B4;575Q0u3-5G3/5V3P4|5Z4*5#5j4/5l4W5*455G475/5X5;4N4 5@534:565n5D4r5G4t60495Y632|5x5M675B580u4I5G4K6e4v5=646j5$5N5(693h0u4Z5G4#6s4M5f5?6w5^5%685C6B4^5G4`6G6g6I6v5L6x6l5{4p3i5a5G5c6T626V6i6X6L6y6N580s5q046?5I6h4e6.665`5P6#0s5F726`6,6|5i6~5A6!5o0s3K7d754)6W785z5O5)715,0s5.5W6f6+7h6-7j5_7a707c5}0s5 7r6t6{4P6}7k6z6O3J6b0s6d7E6H7u774-6/6Z7z3I0s6p7Z7g4~7v7U797l6A3J6D0s6F7Q6U7S7H7w6M6m5Q0s6Q7|7$5K7^6:7`716%0s6)7;7t7%7T5y7x7+7L0x6@8g7 5!6K7*7K580x5F8p8j6J7I8d8n5Q0x3K8y8s7i7)7J6;8x5,0x7q5:5e7?5h8D8v8F6#0x5}8S8B7(8c7_7b3,6b0x7P8K5v8k8u8Y7X3h0x6p8/8V8b6k6 7m5o0x6D8{8=7@8O8,8_3,6Q0x6S888L8a8 8X828Z8.6%0x878(6u8W8@7y92446@0Y5t6*9880909c8-0Q0Y5F9z5d1r2:1g2#2O0$1`2T5g4D2!1x1o2/0F2;3q611o4D9S2h0U0$0^382J5D3y9Z9#8Q5o3j0f2m0F9+839-1Z607G010i0}0(0e9U9j1+0A3ka09`0K0e0}2u0C0?0U0F2E0Pa5760^0|040Hah8M0Ka9ad0R0Fan9901ak0S0l9U0 7s9X2z9*019$2_7Y9)9!aG9,aJ9/2c9;aM9?aJ2L3o0faX0fa13_a90babagaCaZ9`0b0}0B9Ua+aiaw0}0G0Ma:aYaB2@3SaFaH203,aK9=9d3g249:b49x5,3OaYa;8M9|040e4fa:a!3U0}0hbka,a3042Wbpa=0K0p0}0q201Iau3TakamaCblbwbn2abC5gbEbL5?aq2FatbG9`axayaAbCa 0O9%44b3aSb545aP2db99n9y9^aWbdaYblbgbi0qbuao0}0Rb{av0bbrbta*bHbx04bz1EbSa}a=bNbTbvc62lbO4 cdcbb|040Zarca9TbUa@ci260V0U0}9rclavak0M0SbWaCa|cr4xbZb#0Q6b5jbZaT4qb7aQb-7,cN5/b=cYbeavbg0U9 c4a6bQascu1+ak0Gc-a#04boce8McCc:c^avap04b~c|bD0}a_c)a=a-040Ba/d58M0P5F000I00c;a?04azcGbYaLb00K3I6pcOdoaN4HcSb,b(9xdscXcZdDbHa$a(did70Wdic~0t0Z0Z2a0$dibEbFcA4ybndS0}0odLb}dY04cEbXd1cKaI3h6DdtcU7L4Zb+aR8w6#d/dCaXb@by0)0C0q1fdbc}dG0?d*dVd,b14@b%d_5o4^d@d;586Q3OcH3Q5Jeadq3h6%d:dzb.5aeheu7,es9_a=bg9~dibraZd15!a8041w0P0*0Kas0P0O0(0Z0C0UeR0R152E0t0C0Nd%dUcIcmcobRd%cF6td+ducL5seddv5pdxd^e_e@aV3Lb?c*eLeWeOeQ0Oaae7e43Td7da2=c!d2040E0vb 3T0R5F030f0#2zdP1c0f1c0,eWaefu2z1w2G0U1e2b0U2Ee8e*aEe=d-3i5Fetee5D9.b8ey7L5Eb:f0d}f2eMf50FeRf8a)dVbMcteIbPcn2v0O2s0p0b0ye(d#cncpe.d4feblfcfk5!0}0p0ef*fJfge)enf22ueRf?f^f`f.64c+cqgccc0}0Sd!fag4f|e-gj26axfIgn9YfLeb5Re^cQgEexfQ6B3Kbcf1eC0}b_g3f/0ZgR4 c10}c3g0gda%acaef%gif+gSf}gwc.gpdle:e9gCeq3ibb32cPb55+e{ei5*bbd|b=dFf3eN20f6f)d%c{g*gkcnd%f 3qff5gg2gsf/g6g8gAcB0}gb2Kh4gTg-ajdZgU2|gle.gzhta~g?5D5}fPe}b*fTgJ3ihIh2d~c7e0e2hz3v9}f4h7f%f7g#ho5;e;9+e?cNg`dugG0u4rgIe}cW3oemhEcJhG6Bdsh-g 6#6og~fU6ndBh^dnh*fM6CgFg|d?hMe}d{5W9`eD3AeFa4hw3UeKafa%dRiockg9gte,c,iug/hDaD0fep5Dekh i45*egifh/ekhQf20P3Wg(hlgVa.hVc=f)adafg)iwg+gvhcgxgpiCeoh|6$ic9x0uewiMg|eAb;fZbvby0bf@f_iU26hkgZi}f:gfi ghiAalf{iygmh`c_i,dmh)aMcL6?i;b.jnh=gGjne bdh4f#hZh%3Lg1iWj2hWh5f$eReTeVeXeZ0Fe#e%jbhsiDixg,i*g.d(i-hFi9gD72jo7,j#jrb5j#e h_iDiF3h7dj$7Lj;j)9xj;jugNbf9}ilioeGdLeK0h1e1F0Fe10O1^0t0m0)i$hpdWeL0F1 0qj1jUhx04grj5e+h$i!iTkmdje/4ajkdp7Yg_iEh.j*3-j^jph1i{h3f2kakcklhhjBd8iX01cwcyjXh{jZg@7Cj=6=hLcTiJ71hPkKjvf24f0$2Eb!iSjzhi4*j4kQcsjciobIc?f4kejge5f:a(ktjzblbVdI0}dKk b}2t0re(0SkXgBkZ7Yh,kDi07ch;i^j_h@fYkLcfa90q2WkPkff,k~kvc~k:k=iR1%l9k}lkjjg=lnj:h~lqk*7c4IkHj%i6lxk.j60t2G0C3ckTk{3Qk_hdgglDh(lRjlfM7/k$7{iek)hNl{j{cYhR0A1R1%kTl0chjPf{lJ0Fk?lMe.g:kyl^kAj:iHlVm0iLl e_7|fXdDl%cm111xl-jCkql5mdmfkui%iV04lelHa$hvkvbElPg;g9j/3JesiIm0i@mrjsi`l$cZh40re3mOhyjDc=0Nm*k|d6mBm;mxeV0zllfKlS3g6@hJgG8gi3hNn2m2mvh4kNkdm-01d70nfdm@l5jxePmGlE4*c/f{l)0yl+c@m+040MhbmHhA04m)hfnwnlhdm/hfm{mob!fM8pl|8RfSmZb5nLn6dEf2npnrmAkSnbc~mym`lQmSi/8ynM8`23lZ8fgL5/j-i.m}8In+3,kGlub.n^nSj|c#d nqhUnZ0}n9l?3rkznJgD8Sn_8.k(dyn4k,o9mkobg@8$oe3gltnPbalwmwl5o70Ocwm:l/kRnfoBf2k41El+k8o7l3jRf/l=d%kpngkglLnkl4fgmQmjn(n@lUg{balYn|7,8/muo03Tb^bjo5cnae0VmFk^g1c2oA2Kl:nydP2~1c0t2ylNgolGnxjEoTp5jhd(mi5YoacL8{oppin.8oihm$i|j}bsc(mCkgoGk6oJbzkOoLh4oOjboQoEj6p0o@pahCnbd7020h0y0doDo}n8py0)oygYp8knpel@oZl_ocmno$n}mqohe_95o,mvo~jEoxoznXpRjAoFk5oI0qk9pUo8lahrf{pCntpEpSgdo?o^pKmRkfmT9gpjmYp-n1m#p;ppmD0qk;jfp{m=nYptixqbpJn%qfi/9qopqDpl5QqDj,i8p%g@9zqEnOqkb)fOiPgOhSo3o|qtcmp@pXnDi+kom80}mdi-0X9W9D9R9F9O1g0y9Iq?2R2M0t1$q:0X9GaB0(0*0,0P04.
# Tests(insensible à la casse)(Ctrl+I)
(Alt+: ; Ctrl pour inverser les colonnes)
(Esc)