Percolation⚓︎

En géologie, la percolation est un écoulement d'eau à travers un sol sous l'effet de la gravité. Le sol n'étant pas compact, l'eau s'infiltre dans les "vides" et pénètre en profondeur.

Précisons tout de suite que l'on appelle sol, l'ensemble du milieu : la surface sur laquelle nous marchons et l'épaisseur de terre et de roche sous nos pieds !

On se propose ici de simuler grossièrement ce mécanisme en se demandant si un écoulement d'eau peut atteindre une certaine profondeur dans un sol.

Le sol⚓︎

Le sol sera représenté en Python par une liste de listes contenant des entiers. Dans cette liste :

  • 0 représente une cellule vide ; l'eau peut la traverser.
  • 1 représente de la terre ; l'eau ne peut pas la traverser.
  • 2 représente de l'eau.

On garantit que, mis à part une cellule vide sur la première ligne, tous les bords de la grille sont en "terre".

On donne ci-dessous un exemple de sol "sec" (aucune cellule ne contient la valeur 2) :

🐍 Console Python
>>> sol = [
...     [1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
...     [1, 1, 0, 1, 0, 0, 0, 0, 0, 1],
...     [1, 1, 0, 1, 0, 1, 1, 1, 0, 1],
...     [1, 1, 1, 1, 1, 1, 1, 0, 0, 1],
...     [1, 0, 1, 0, 1, 0, 0, 0, 1, 1],
...     [1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
...     [1, 1, 1, 0, 0, 1, 1, 1, 0, 1],
...     [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
... ]

Comme on peut le voir, une cellule de la première ligne est "vide" (sol[0][5] vaut 0). L'eau peut donc pénétrer par cet endroit.

Comme on le verra dans la suite, l'eau va s'écouler dans ce sol. On peut récupérer un "sol sec" (sans aucun 2 dans la grille) en faisant sol = nouveau_sol().

Génération d'un nouveau sol

La fonction ci-dessous est accessible dans la zone de saisie, inutile de la recopier !

🐍 Script Python
def nouveau_sol(nom='base'):
    """
    Renvoie un sol sec
    Trois sols sont proposés
    Par défaut on récupère le sol 'base'
    """
    sols = {'base': [
        [1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
        [1, 1, 0, 1, 0, 0, 0, 0, 0, 1],
        [1, 1, 0, 1, 0, 1, 1, 1, 0, 1],
        [1, 1, 1, 1, 0, 1, 1, 0, 0, 1],
        [1, 0, 1, 0, 1, 0, 0, 0, 1, 1],
        [1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
        [1, 1, 1, 0, 0, 1, 1, 1, 0, 1],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    ],
        'puits': [
        [1, 0, 1],
        [1, 0, 1],
        [1, 0, 1],
        [1, 0, 1],
        [1, 1, 1],
    ],
        'diagonale': [
        [1, 0, 1, 1, 1, 1, 1, 1, 1, 1],
        [1, 0, 0, 1, 1, 1, 1, 1, 1, 1],
        [1, 1, 0, 0, 1, 1, 1, 1, 1, 1],
        [1, 1, 1, 0, 0, 1, 1, 1, 1, 1],
        [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
        [1, 1, 1, 1, 1, 0, 0, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 0, 1, 1, 1],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    ]

    }
    return [ligne.copy() for ligne in sols[nom]]

L'écoulement⚓︎

Lors de l'écoulement, l'eau peut se déplacer dans trois directions :

  • vers le bas
  • vers la gauche
  • vers la droite

L'animation ci-dessous présente l'écoulement dans le sol précédent.

percolation

Dans ce cas, l'eau peut atteindre les profondeurs 0 à 5, mais pas la 6 ni la 7.

La fonction à écrire⚓︎

On écrira une fonction percolation prenant en argument les coordonnées de la cellule de départ (ligne i et colonne j) ainsi qu'une profondeur maximale à atteindre. La liste décrivant le sol sera déclarée dans le corps du programme et modifiée directement.

La fonction renverra True si l'eau atteint cette profondeur, False dans le cas contraire.

On utilisera une fonction récursive procédant ainsi :

  • à chaque appel, on indique dans le sol que l'eau s'est écoulée jusqu'à cette cellule (on place un 2 dans la cellule correspondante)
  • on vérifie ensuite que la profondeur de la cellule passée en argument est égale à la profondeur cherchée. Si c'est le cas, on renvoie True
  • dans le cas contraire :
    • on vérifie que la cellule de dessous est vide. Si oui, on explore cette cellule en appelant à nouveau la fonction. Si cette exploration renvoie True, la fonction renvoie True
    • on procède de la même façon avec les cellules de gauche et de droite
    • une fois ces trois cas étudiés, si la fonction ne s'est pas encore terminée (aucune des explorations n'a renvoyé True) on renvoie False

Attention

Dans la mesure où la fonction modifie la liste Python représentant le sol (en l'inondant avec des valeurs 2), il est nécessaire de générer un nouveau sol avant chaque test

Exemples

On génère un sol sec grâce à la fonction nouveau_sol définie plus haut. Le point de départ est en i=0 et j=5.

🐍 Console Python
>>> sol = nouveau_sol()
>>> # L'eau atteint-elle la profondeur 4 ?
>>> percolation(sol, 0, 5, 4)
True

On n'oublie pas d'assécher le sol avant de faire un nouveau test :

🐍 Console Python
>>> sol = nouveau_sol()
>>> # L'eau atteint-elle la profondeur 6 ?
>>> percolation(sol, 0, 5, 6)
False

Au travail⚓︎

Compléter ci-dessous la fonction percolation :

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
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 : 5/5
.128013lS]te-UdA5f18umaèg,_F/R=V{in 6)yàqPhcD[(bEsx.p;r4jC'90"ovT+w73?êOk:é }2I030c09080k0v050L0.0F050k0L0L0s0X080v0O0X020x030L0i0j0j0k0Q0A02060Y050i150Y0w0.000k0j0O0P0.0r091f0Q0C0i090L030q1c1e1g1i1a0O02031N1G1Q0q1N1a0c0v0Z0}0 11130E0v0m0E051'0E0818030^0J05091Z10120X1%1(1*1(081:1=1.080Q1O080E0}1l0L0O0k0w130:0X1@1#0X0f0`090w1t091.2a2c2h1_2k1=2n0j2p02040.0D0Q0Y0O0Y0L0v1o1q0?280Q0Q090F2K1G2r0w1O0q262W2325241/0c2t131*0w2m2H1.1W1Y0~1^2)0v2+0w0Y2/1.0O2P1O2U2W301b2b1q2;2i2_0Q1f05180.0g2T3419332s361_383a3c0:3f2c3h2U2(0X3m0k3b020.0'3q2V1a3t3k133w3y0.0R3C3s343u3I3c0e3M3E3O3G3v0Y393x3c0y3T3i351!3l3Y3n3z0%3%3F3)3H3+3!3z0h3/3V3;3X3Z3J0V3`3j3|3Q020g0W413(2=3}3,0g3e1H3g3U424a440g3p4f3r4h49373?3y0g3B4n3D3'3P4s180g3L4w3N4i4r3~4B3S4E4p4z4I453$4L4y3W4k3.4R3:4j4A453_4W3{4Y4O0g404$4G3*4O0:474+4q4-3,0:4e304M4T4Z0:4m4`4S434}4v504X4H4@4D554%573@0:4K5a4,3=4.4Q5g4=5i4@4V5l4N4@4#5q4|4.4*5u524O0'4:5y4'3,0'4_4g515E3@0'4 5I564?5L545O5b5Q3y0'595T5h4b5L5f5Z5m5#5W5k5'5r5L5p5,5v5F5t5:5z5F5x5@5K3y0R5C5{5c5}5H4o5J61180R5N645P5n3@0R5S6a5U6c5}5Y6g5!440R5%6l5(6n5+6q5-5}5/6u5;6d5?6y5^6d5`6C5|180e5 6G66020e634x6b5)6I696Q6h6S6N6f6V6m4Z0e6k6!6r6$6p6(6v6I6t6,6z3y0e6x6:6D6=6B6^6H6N6F6|6M0y6K705V180y6P4F6)4O0y6U2W2}092W2/2Z0c252'3W0F2`2z0=1X1O7f2 3g3M037o0?7v6m180!0K0r0r0K3M0.651_0Y180s7J7L130j0v4B483P180t0;0G7I4E7K6R7N027P7%7R0X7T1873797X020K0d0b7Q7(7O7{6W7/027d0x837-0+180?0f7~6m0f180O090Q7o0 2S4E7-17020I7x6R0w180L1l8p6W8m0n8a6r180v8v5!8x8z7?0S8D5(8F7,8q8d2E0f0o1f0M8J3u8m0z0,3T0.8!7'6W8r028t058U3W8m0H8+438B8/4a8m078.8k8N028I8`8w18078G3W7)7+308$7C7@7_3T0x8#975(86020v898M8%8;9k5!94953g9e7?2}0Y8Q8S8=2i8m8Y4L9d9d85182P080i0Q0w923|0+0F7D0Q1D8Z8#9F02090{099y1_9A9T9D9s3W9g9i9M4j8s8u8~8E188_328{8C9n5(7)0#9,2i80788l909?7w8{8}9@8 02919`3u9p9~3l7Y7!7$a89;029B4`9'9'9V9+ac4T8d8f8h0k8jak8K188o9:8A8(9/aA8V188yat8:9haf139|aP7.7U459!138L967-8'a7a5a9aLaZ8{9u9w0k8TaEaJ028X9%apaq6R9g9H9J9LaM4a9O9Q9S4L9capar9ja)9laG8*a/8,9=aW3v9maIbdaaa43ra!18a$3r9(3|7)0aaSa0bf8@aSaea~37ah7#bx18an4ga@9Ea_8Bb79rbn028e8g1lay0v1pbF8nbf8'8)bXa(bO9^b$aSa#bz18bubB1_bwbc3|aYb'b9a+8Ra-bXa=9CbJa^6Wa`0@a|aSb0020!9R9Zb3a@b6b*9.bbbib?beb=9-aOcl9za3bZbob,029}b/7SaUa16Rbycw0XbAb8987ZbEco9#bGa?cdbL9hbNbqbPbRaxaza%alaDcicmb#cJaXaKcfcncZcp02b%cRa6ctcvcF5(b;c*cKc,c(b`9xc$0X8WbH4oc0c15!c39I9Kc69Pc8ca9bcNc29Gc4d8cCc70p3x0Lcb4`84cO88b*8c022_0i0Z090k0i0oc#c^c%bYc~8'2_0jbf94bf0L2f02001C0Y080P0J1009dR0idT0Pb}d174130$3c9Uc~0L0c18dZd#d;dUd?d$4;3ud.d+8!1y0w0Z0Y0v1?0i1q8)0.dn0F7W3Wd|3z8#c9e20|8)ei1p080.9u2G0L0-1Fd`ecd/ee8!0D1g0.0c0-0fdAem1p0.0Q0-0F0i0O0l2P0.1=e81l1r010'0VdVdX00eUeWeb3|ed9dd^e)dSdUa?bPejct9qc.a90ucM9U6RdOd:e+eXdnd^bXd'3za202bl3Dd3br8?ckdEaT7Vc~b@e=5!c@cWaBc`cCfjbmcAc'fncyb)fsfefcfg2Vf99 aU7;f4c-fz7-fo2VfEbvftfffrc=3ufI7BflfFf36RfRf407fUb4c0f4f6fSfQfMfxfOb^fif*fka:fUfAb:fCfufP3WfXfqfmf`3|80fDf}f=fHf^fNf~f-c?g6f+g8fhga7:f_g9f)ggg7g4fWf/fpa9fZe^d4flf'g5fwf:bjgm7 gofJg3fLgkgcgAf.gxgpalgIgf02g2a'gFaVglgSczgRfvgTgHgSgQgMgVbXgrb f$f}gvgngKgDgXf 4af|g;gif{gCf(gzg'gUgYg$fTg~g!gYgWg%h0ghgegjgPh9fGg.gZgycjaaf!f8f%bfg@h7g=fBgGhhfagdhegBg/g|higNhbh1f;h3htc+hBg`hsgLh2h8g hqf@hKg:hpg_g0g{fKh5g(hkd3hmc~hohMhPcxhRhzhuhIhVhyhXh)fdhghLhEhYhOhUg?hWgEhNh4h=h'h_i2h~g^hahJh@hSflg)aoh#g,hni6hTi8h/iah,hHhFh^g}i0hGc_h.h}h+h;h|hrimiyikiwiBh i5h:iGizhQhch{iDiAh6ich!g+a9g-hxiFi7hwgJiXijiZgOiQi4iKh*i#h(i*h?i(iriHi,i)iOiLi:hAipibi@i%hbi`h-i|inc_idbIb5f}j6d2j86We{dQe}0O0i2J0Lf0g7f2f?dFf'f#bJh$fci3i;i.g1hdfViWj1c+jaf7ifiUihiIiYjAi!hDjwi^i+jCj5iSjsigh%iii-jPh?jNi{h`gcjE19hljVjujXi~jLgOj#j2j%itdFj(jrdealiVi!jRdFiviPjzjoi/hZgsk48@jTbKjddPd^1W0k0m1p3xdYe}f1aS8-k7kbj|jIi?jOi i9j;ioj?iqj$i=j c f,jZjvkBjxj-kuj/j0k3gwktkIkGkKkRkvilkDk9kpe_jHjWjJi$kMkwkOhfkxiuj3iCkViEkXkFk:k2iNk@i_k*jBk|j~k~i'k6g*jUk#j,k%jYk`jQl0hClbk)k_k(kWldlhlfk4kHj=kClik;lpk^j'kajckrk$kQlnkJl7j.llkTlzkSixiJlGiMi1lAlykylolkkPk=hvlglqlQhflSj_j*l5j@k5lWk}l'k l)l1l+lcl-lelLlJlSk1k{l/ljl;l9l%ltkZ8!jtl$lmlOlMl?k.lIl|m3k-kzi}kLlDlHjKmflKl$fylUlsmkk?mml^l{mqlag7lZjGlwl6lNmblPmsmim6mcj4k0m7mhlRlriLk,mImGk/mtl}molTmEl2ieiTmym2lEm4l=mMmumDmLl_lVm*lXm(mTkAlFm9m$mBm5m:maj^lum0j9jTf40/e-cOa{dih=kodH181}2+dL180Ncr027o0O0AbX0I0zc6180f3Yc(ncdoi.0Yd*9ha}h=b!29bXj}aFdJg(ab500q7z7g1R2~1G7i1G087knS2$2X0k1;nN0q7i1MmH0X2P0j0oeD0+090o0E0'181y1A1C1E0.f21R3h1N0*1q1n0`0vdnenez7o1e2`2J0-ePn_0Z1g0vnY1=0|7y7p02cH7$nM3z0@7Kop7^7`nLoleAeC2@e30Lng1Tn}020G0l0|0 enn)0veN1?nu0n0.eG2@1Wn^eA2coJ1?ok7Ac#op0.oW050Udz0ie8o+0LemeJ0Y0i050-1?0S0i0L1C0U0B0}0@081?0F9X1m1=0N0.0Tp21?0k2RbV1q1z0O0)0F0E8f0keA1?2P7o0w2IeB2P0Qpp0|p505p7n_eB0Sp00Zo3oa1EoD1U1P02n 0.p3o:1?2m1c2JoPp410pp0.dWo42MoKeIeK0Q2IpH08ob0,ePpoa+1p0?9Jp!oKpApC0.pe9Ip6pTo:0aq10.0-0mkj0.p0oKp?0wp^pxpHeq1?0(0.060voSjioReG2Pe0e2o!opc9b2oppLoF0GoYoc0}pZps230_2Pqqph0M0O053Y1?1c0Fp5111X1z2memoipQ2Eo3eA0vpr2K0|0Ip$oRq80ipl09oR0cq$p30zn`n|1ao@3h1*oF0Do?pxplpee5q=oS1q0Z0-0Q9ie3pQo?em0c0UnY3Y2'o)pop|o@q2empH0?q|1Gr01arypNqm0}o/qZpY0LqLpQ1Ep3p~qPp+qE9Hr3p`rk0O8e05osolcTbT2K0I8)oRdwdydA0o0vr'o?r)dB0SoRc|a-noow7Ap9060U0`0.oe1nrX7AqxcboprIqse1rf1Wq)qX0wemo#7gs41Goprw0qrArA1NrCdAeK2+py0.09qNrNbU1p0|0wrkeH2me10AobsgdbqyolrIst8es12b0|ayp3oUeOqc8Pp@09p_8t0i0E0_p.1?p:qrsFqus27gdl9YsjolslrA0qq~1an#0@0_0{02.