Le jeu de la vie

Le jeu de la vie est un « automate cellulaire » inventé en 1970 par John Horton Conway.

Une « partie » se déroule sur une grille, théoriquement infinie, divisée en cellules carrées. Chaque cellule est soit « vivante », soit « morte ».

On appelle voisin d'une cellule, une cellule qui partage au moins un « coin » avec celle-ci. On a représenté ci-dessous une cellule (coloriée) et ses huit voisins (pointés).

Voisins d'une celllule

L'état actuel d'une grille représente une « génération ». Afin de calculer la génération suivante, on parcourt toutes les cellules de la grille actuelle et, pour chacune, on applique l'une des règles suivantes :

  • si elle est morte et possède exactement trois voisines vivantes alors elle sera vivante à la prochaine génération. Si elle ne possède pas trois voisines vivantes, elle reste morte ;

  • si elle est vivante et possède deux ou trois voisines vivantes alors elle restera vivante à la prochaine génération. Dans le cas contraire, elle meurt.

Malgré leur simplicité, ces règles permettent d'engendrer des comportements complexes1.

On se propose dans cet exercice de mettre en œuvre le jeu de la vie avec Python. Pour cela, plusieurs questions sont proposées. Ces questions sont indépendantes et peuvent être traitées dans l'ordre souhaité. La dernière question regroupe l'ensemble du code et permet de visualiser l'évolution d'une grille.

La grille de jeu sera représentée par une liste de listes contenant les valeurs 0 (cellule morte) ou 1 (cellule vivante). On garantit que les grilles sont toutes des carrés de largeur et hauteur égales à un entier \(n\) strictement positif.

Dans toute la suite, les variables i désigneront des indices de lignes et j des indices de colonnes.

On fournit une fonction grille_aleatoire qui prend pour paramètres la dimension taille d'une grille (taille est un entier strictement positif indiquant le nombre de lignes et de colonnes de la grille) et un nombre flottant proba_vie (compris entre 0.0 et 1.0). Cette fonction renvoie une grille de la dimension souhaitée dans laquelle chaque cellule à une probabilité proba_vie d'être vivante.

Ainsi :

  • grille_aleatoire(7, 0.3) renvoie une grille de \(7\times 7\) dans laquelle chaque cellule a une probabilité de \(p=0,3\) d'être vivante ;

  • grille_aleatoire(10, 0.0) renvoie une grille de \(10\times 10\) entièrement remplie de cellules mortes.

Cette fonction est d'ores et déjà accessible dans tous les éditeurs. Il est inutile de l'importer.

Code de grille_aleatoire

On fournit le code de la fonction grille_aleatoire pour information.

🐍 Script Python
from random import random

MORT = 0
VIVANT = 1

def grille_aleatoire(taille, proba_vie):
    return [
        [VIVANT if random() < proba_vie else MORT for _ in range(taille)]
        for _ in range(taille)
    ]
Visualisation

On propose dans un premier temps de visualiser le fonctionnement du jeu de la vie en observant l'évolution d'une grille lors de plusieurs générations.

On fournit donc une fonction visualisation qui prend en paramètres une liste de listes grille représentant l'état initial de la grille et un entier nb_generations qui indique le nombre de générations à simuler.

Cette fonction calcule l'état de la grille au fil du nombre de générations indiquées et dessine la grille correspondante sous l'éditeur. À ce titre certains réglages sont modifiables par le biais des variables TAILLE_CELLULE (taille d'une cellule en pixels), DELAI_SECONDES (délai entre les affichages de deux grilles) et COULEUR_VIVANTE (couleur d'une cellule vivante).

Cette section ne comporte pas de tests mais seulement une représentation visuelle. Vous pouvez l'utiliser afin de tester des grilles aléatoires ou des motifs particuliers.

Restons raisonnables

Ne perdez pas de vue que nous travaillons dans le navigateur et que l'exécution de code Python n'est pas immédiate.

Dessiner des grilles de grande taille ou demander un grand nombre de générations risque dans certains cas de ralentir le fonctionnement du navigateur.

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

La grille sera dessinée ici

Voisins valides

Une grille étant donnée, on souhaite calculer la grille de la génération suivante. Pour cela, il faut, pour chaque cellule, compter son nombre de voisins vivants.

Les cellules du centre de la grille ont bien huit voisins. Celles des « bords » n'en possèdent toutefois pas huit. Une cellule située dans un « coin » de la grille ne possède par exemple que trois voisins.

On demande dans un premier temps d'écrire une fonction voisins qui prend en paramètres une liste de listes grille représentant une grille ainsi que deux coordonnées valides i et j et renvoie la liste des coordonnées des voisins de la cellule de coordonnées (i, j).

Égalité de listes

Les tests de cet exercice utilisent une fonction egales qui renvoie True si les deux listes passées en paramètres contiennent exactement les mêmes éléments sans tenir compte de leur ordre d'apparition dans chacune.

Exemples
>>> grille = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> voisins(grille, 0, 0)
[(0, 1), (1, 0), (1, 1)]
>>> voisins(grille, 0, 1)
[(0, 0), (0, 2), (1, 0), (1, 1), (1, 2)]
>>> voisins(grille, 1, 1)
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1), (2, 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

.128013nTimOwgyk02P;o, V56]uRMa+lI84t/sbr[vce.3)Afhj-:1S=97dNp(050#0M0E0y0d0A0G0q0L0A0y0G0G0Y010E0d0%010406050G0v0e0e0y0I0i040X0o0A0v0|0o0b050F13151719110%041i1p051s0F1s1u1p110#0d0K0;0?0^0`0S0d0h0S0A1I0S0E0 050,0H0A0M1D0@0_011H1J1L1J0E1R1T1P0E0H0o0#191Q0I1q0E0S0;1c0G0%0y0b0`0l011V1F010R0.0M0b0y0e0M1P1`1|211X241T27290 0a0q0m0I0o0%0o0G0d1f0b0q0*1^0I0I0M0L2u1i2c0b1q0F1?2H0E1;1:1=0#2e0`1L0b262r1P1A1C0=1W2R0d2T0b1-1B1P0%2A1q2F2H2/121{2v2Z222(0I160A0 0q0W2E2?102=2d2^1X2`2|2~0l311|332F2Q01380y2}040q0O3c2G113f360`3i3k0q0D3o3e2?3g3u2~0s3y3q3A3s3h0o2{3j2~0t3F342@1E373K393l0!3P3r3S3t3U3M3l0C3Y3H3!3J3L3v0Z3*353,3C040W0k3;3R2!3-3V0W301j323G3=3}3@0W3b423d443|2_3$3k0W3n4a2G1r2-1i2X2K0#2O3g0L1-2a1q4o1t4m2;4j1q4t0*2.3+460 0x0f0w0c3y0q3Q3g0o0 0Y4N4P3I0e0d0 3`4B4c3B0 0r0B0r0Q0$4M4B4O3Z3}4R044T4/4V3,4X0 412/06504`3}0j0 0*0R3y52220g2~584;2_0R0 0K0o0d2s0b0G5d4G220~040(5o452_0 0h0I0.1T5u4d1X5r0p4U5e370 0d5C3g5F5H5p5J040T5M3I5r0P0V3F0q5!4:5Q3t0 0,5A0M5P5v1X4?4^2/5$5.3t0H0 2h5U3,5r5t4B595R5y5+5|3}5W3F065#5?5D5(041A2A2C0d1g5n4_5I0`5:5-6c015~5 2;6m014?0U65224|3^6z5E0 5G6l5%6w0 6y606v6B4~32610`5W6G5=6R6r0 6t6Q6v6x6D0`6O6%6X046U326b3g6B4!6u6I6T6p5N6Y6*6$6M6I6)6~5@6+6-3d6/4W4Y6C716q6^6H725~6*6;6*5O7d6q6}6?72707n7b0 0P742G765}6{7a6:786=6!6@6F6_774}7i7s7u3l6W7f7z7H797q6`6,7G3,7m7D7o786P3d7N7K7V667y7S7Q7#4k6v7j6V6N7B7J047t7)5q7+7Y6q7p7~7T7L7w3}807$7:7s0P5Z5#6W0b0 2A130A0,0E7{5/4S8l6S0 0J0u8b5!6W54040R3K8o3h555L7P7x7U7k4%6e5T8H3I0o5b042$8A8e6e0d6g2u6k7,8F5Y4#6a6a8v5K578L4{7@8+4=0 028i0n5;6.8d5K8A4?0z8R8C8{8:8=8~045*0A5B8.228N0 1|0#8A7h988m048;0E8?938K7=6I8|930#9n8^6#919k9395978Y7*048!4 8$9G845w048g0v8i0y8k8E8/040N6*8S0y0%0%269d9Q7|5s6Z876I8S8D9o729q9g6d1A7^838_5S90048}9:8B8J7^0P8a8#8c6v8w2A0E0v0I1h9}8S9L9N9P4 1i4D0M2H2,ak4n1B4p2K2M2I1,1.2K0y1San0F4o11aA0+0-0/04.

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

.128013nTimOwgyk02P;o, V56]uRMa+lI84t/sbr[vce.3)Afhj-:1S=97dNp(050#0M0E0y0d0A0G0q0L0A0y0G0G0Y010E0d0%010406050G0v0e0e0y0I0i040X0o0A0v0|0o0b050F13151719110%041i1p051s0F1s1u1p110#0d0K0;0?0^0`0S0d0h0S0A1I0S0E0 050,0H0A0M1D0@0_011H1J1L1J0E1R1T1P0E0H0o0#191Q0I1q0E0S0;1c0G0%0y0b0`0l011V1F010R0.0M0b0y0e0M1P1`1|211X241T27290 0a0q0m0I0o0%0o0G0d1f0b0q0*1^0I0I0M0L2u1i2c0b1q0F1?2H0E1;1:1=0#2e0`1L0b262r1P1A1C0=1W2R0d2T0b1-1B1P0%2A1q2F2H2/121{2v2Z222(0I160A0 0q0W2E2?102=2d2^1X2`2|2~0l311|332F2Q01380y2}040q0O3c2G113f360`3i3k0q0D3o3e2?3g3u2~0s3y3q3A3s3h0o2{3j2~0t3F342@1E373K393l0!3P3r3S3t3U3M3l0C3Y3H3!3J3L3v0Z3*353,3C040W0k3;3R2!3-3V0W301j323G3=3}3@0W3b423d443|2_3$3k0W3n4a2G1r2-1i2X2K0#2O3g0L1-2a1q4o1t4m2;4j1q4t0*2.3+460 0x0f0w0c3y0q3Q3g0o0 0Y4N4P3I0e0d0 3`4B4c3B0 0r0B0r0Q0$4M4B4O3Z3}4R044T4/4V3,4X0 412/06504`3}0j0 0*0R3y52220g2~584;2_0R0 0K0o0d2s0b0G5d4G220~040(5o452_0 0h0I0.1T5u4d1X5r0p4U5e370 0d5C3g5F5H5p5J040T5M3I5r0P0V3F0q5!4:5Q3t0 0,5A0M5P5v1X4?4^2/5$5.3t0H0 2h5U3,5r5t4B595R5y5+5|3}5W3F065#5?5D5(041A2A2C0d1g5n4_5I0`5:5-6c015~5 2;6m014?0U65224|3^6z5E0 5G6l5%6w0 6y606v6B4~32610`5W6G5=6R6r0 6t6Q6v6x6D0`6O6%6X046U326b3g6B4!6u6I6T6p5N6Y6*6$6M6I6)6~5@6+6-3d6/4W4Y6C716q6^6H725~6*6;6*5O7d6q6}6?72707n7b0 0P742G765}6{7a6:786=6!6@6F6_774}7i7s7u3l6W7f7z7H797q6`6,7G3,7m7D7o786P3d7N7K7V667y7S7Q7#4k6v7j6V6N7B7J047t7)5q7+7Y6q7p7~7T7L7w3}807$7:7s0P5Z5#6W0b0 2A130A0,0E7{5/4S8l6S0 0J0u8b5!6W54040R3K8o3h555L7P7x7U7k4%6e5T8H3I0o5b042$8A8e6e0d6g2u6k7,8F5Y4#6a6a8v5K578L4{7@8+4=0 028i0n5;6.8d5K8A4?0z8R8C8{8:8=8~045*0A5B8.228N0 1|0#8A7h988m048;0E8?938K7=6I8|930#9n8^6#919k9395978Y7*048!4 8$9G845w048g0v8i0y8k8E8/040N6*8S0y0%0%269d9Q7|5s6Z876I8S8D9o729q9g6d1A7^838_5S90048}9:8B8J7^0P8a8#8c6v8w2A0E0v0I1h9}8S9L9N9P4 1i4D0M2H2,ak4n1B4p2K2M2I1,1.2K0y1San0F4o11aA0+0-0/04.
Voisins vivants

Une version fonctionnelle de la fonction voisins de la question précédente est disponible dans cette question. Il est inutile de l'importer.

Cette fonction étant connue, il faut désormais parcourir l'ensemble des voisins valides d'une cellule afin de connaître le nombre de voisins vivants parmi ceux-ci.

On demande d'écrire une fonction voisins_vivants qui prend en paramètres une liste de listes grille représentant une grille ainsi que deux coordonnées valides i et j et renvoie le nombre de voisins vivants de la cellule de coordonnées (i, j).

Exemples
>>> grille = [[1, 1, 0], [0, 1, 1], [0, 0, 1]]
>>> voisins_vivants(grille, 0, 0)
2
>>> voisins_vivants(grille, 1, 1)
4
>>> voisins_vivants(grille, 2, 1)
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

.128013nTimOwgyk02Po, V56+uRMa]lI84t/sbr[vce3)Afhj:1S=97_dNp(050Z0L0D0x0d0z0F0p0K0z0x0F0F0V010D0d0#010406050F0u0e0e0x0H0i040U0n0z0u0`0n0b050E111315170 0#041g1n051q0E1q1s1n0 0Z0d0J0/0;0?0^0Q0d0h0Q0z1G0Q0D0}050*0G0z0L1B0=0@011F1H1J1H0D1P1R1N0D0G0n0Z171O0H1o0D0Q0/1a0F0#0x0b0^0l011T1D010P0,0L0b0x0e0L1N1^1`1 1V221R25270}0a0p0m0H0n0#0n0F0d1d0b0p0(1?0H0H0L0K2s1g2a0b1o0E1;2F0D1/1.1:0Z2c0^1J0b242p1N1y1A0:1U2P0d2R0b1+1z1N0#2y1o2D2F2-101_2t2X202$0H140z0}0T2C2;0~2:2b2?1V2^2`0}0l2~1`302D2O01350x2{040M392E0 3c330^3f3h0C3k3b2;3d3q0}0r3t3m3v3o3e0n2_3g0}0s3A312=1C343F36040X3K3n3N3p3P3H040B3T3C3V3E3G3h0W3t1p2+1g2V2I0Z2M3d0K1+281o3:1r3.2/1h2 053^0(2,3$2Y3e0}0w0f0v0c3t0p3L3d0n0}0V4e4g3D0e0d0}0k3#323%0b0}0q0A0q0O0!4d403a4f3U474i044k4D2E4F46204o2|3A063B4t470j0}0(0P3,4G200g0}4f4L454V2@0P0}0J0n0d2q0b0F0Y0J1z1`0D0F4#4O1V0|040$504-340}0h0H0,1R563M47530o4l4$58040d5e3d5h5j513p0}0R5o3D530N0S3A0p5C4N575t040D0n0*0z5r5F014I4K2-5E5f4P4p044r4+065D5S3d4X040P3F5M5T5l0d4`4=4@5w3%5q4+5#3D4v040R5/4?2!5+4h4(5m1f5^4m4u4:5:2!4 4+675g0}556d5k5G5a5c0L5=6f045i666j485m6o205@5R6e2@5u6w520}5z5B5!5D6A5l5I5K613D4I0t5Q2 5_68046l0z5d6i5s01530I6D5G5.4;5 652/6t530y6(6!5N5{5}6,5;6@5,0^6;6H5C6K0^5%2y0D0u0H6.6T736u6M3g3K0E430L2F2*7j3/1z3;2I2K2G1*1,2I0x1Q7m0E3:0 7z0)0+0-04.

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

.128013nTimOwgyk02Po, V56+uRMa]lI84t/sbr[vce3)Afhj:1S=97_dNp(050Z0L0D0x0d0z0F0p0K0z0x0F0F0V010D0d0#010406050F0u0e0e0x0H0i040U0n0z0u0`0n0b050E111315170 0#041g1n051q0E1q1s1n0 0Z0d0J0/0;0?0^0Q0d0h0Q0z1G0Q0D0}050*0G0z0L1B0=0@011F1H1J1H0D1P1R1N0D0G0n0Z171O0H1o0D0Q0/1a0F0#0x0b0^0l011T1D010P0,0L0b0x0e0L1N1^1`1 1V221R25270}0a0p0m0H0n0#0n0F0d1d0b0p0(1?0H0H0L0K2s1g2a0b1o0E1;2F0D1/1.1:0Z2c0^1J0b242p1N1y1A0:1U2P0d2R0b1+1z1N0#2y1o2D2F2-101_2t2X202$0H140z0}0T2C2;0~2:2b2?1V2^2`0}0l2~1`302D2O01350x2{040M392E0 3c330^3f3h0C3k3b2;3d3q0}0r3t3m3v3o3e0n2_3g0}0s3A312=1C343F36040X3K3n3N3p3P3H040B3T3C3V3E3G3h0W3t1p2+1g2V2I0Z2M3d0K1+281o3:1r3.2/1h2 053^0(2,3$2Y3e0}0w0f0v0c3t0p3L3d0n0}0V4e4g3D0e0d0}0k3#323%0b0}0q0A0q0O0!4d403a4f3U474i044k4D2E4F46204o2|3A063B4t470j0}0(0P3,4G200g0}4f4L454V2@0P0}0J0n0d2q0b0F0Y0J1z1`0D0F4#4O1V0|040$504-340}0h0H0,1R563M47530o4l4$58040d5e3d5h5j513p0}0R5o3D530N0S3A0p5C4N575t040D0n0*0z5r5F014I4K2-5E5f4P4p044r4+065D5S3d4X040P3F5M5T5l0d4`4=4@5w3%5q4+5#3D4v040R5/4?2!5+4h4(5m1f5^4m4u4:5:2!4 4+675g0}556d5k5G5a5c0L5=6f045i666j485m6o205@5R6e2@5u6w520}5z5B5!5D6A5l5I5K613D4I0t5Q2 5_68046l0z5d6i5s01530I6D5G5.4;5 652/6t530y6(6!5N5{5}6,5;6@5,0^6;6H5C6K0^5%2y0D0u0H6.6T736u6M3g3K0E430L2F2*7j3/1z3;2I2K2G1*1,2I0x1Q7m0E3:0 7z0)0+0-04.
Génération suivante

Des versions fonctionnelles des fonctions voisins et voisins_vivants des questions précédentes sont disponibles dans cette question. Il est inutile de les importer.

Ces fonctions étant connues, on peut désormais, connaissant une grille, calculer la grille à la génération suivante. Pour ce faire :

  • on crée une nouvelle grille ne contenant que des cellules mortes,

  • on parcourt toutes les cellules de la grille actuelle et, pour chacune, on met à jour l'état de la cellule correspondante de la génération suivante en appliquant les règles du jeu de la vie.

On rappelle les règles du jeu :

  • si la cellule actuelle est morte et possède exactement trois voisines vivantes alors elle sera vivante à la prochaine génération. Si elle ne possède pas trois voisines vivantes, elle reste morte ;

  • si la cellule actuelle est vivante et possède deux ou trois voisines vivantes alors elle restera vivante à la prochaine génération. Dans le cas contraire, elle meurt.

On demande d'écrire une fonction generation qui prend en paramètres une liste de listes grille représentant une grille et renvoie une nouvelle grille représentant la génération suivante.

Exemple
>>> grille = [[1, 1, 0], [0, 1, 1], [0, 0, 1]]
>>> generation(grille)
[[1, 1, 1], [1, 0, 1], [0, 1, 1]]

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

.128013nTmOwgPoC,6]uRaUH8bsr[vcezj-1S9_d(Lxiyk02; V5àMlI4t/.EG3)Afh:=é7qNpD050H0z0Z0p0L0W0u0R0y0W0p0u0u0.010Z0L0?010406050u0n0d0d0p0v0M040E0i0W0n180i0b0R020p0d0?0Q0R0o0z1i0v0;0n0z0u050!1f1h1j1l1d0?041J1Q051T0!1T1V1Q1d0H0L0x101214160,0L0g0,0W1-0,0Z1b050{0t0W0z1(1315011,1.1:1.0Z1_1{1@0Z0t0i0H1l1^0v1R0Z0,101o0u0?0p0b160P011}1*010+0}0z0b1w0z1@2l2n2s1 2v1{2y0d2A040a0R0h0v0i0?0i0u0L1r1t0_2j0v0v0z0y2V1J2C0b1R0!2h2+0Z2f2e2g0H2E161:0b2x2S1@1#1%111~2^0L2`0b2b1$1@0?2!1R2)2+3c1e2m1t302t350v1i0W1b0R0D2(3g1c3f2D3i1 3k3m3o0P3r2n3t2)2@013y0p3n040R0(3C2*1d3F3w163I3K0R0Y3O3E3g3G3U3o0T3Y3Q3!3S3H0i3l3J3o0l3)3u3h1)3x3.3z3L0:3?3R3_3T3{3:3L0s3 3+413-3/3V0F473v493$040D0O4e3^314a3|0D3q1K3s3*4f4n4h0D3B4s3D4u4m3j433K0D3N4A3P3@3#4F1b0D3X4J3Z4v4E4b4O3(4R1S3a1J2~2.0H2=3G0y2b2K0^1$1R390z3b3s3Y054+0_4?4T3x1b0V0e0o0c3Y0R4L3,0i1b0.5456490d0L1b4k4R4C3#1b0S0X0S0*0=534R55404n58045a5s5c4n5e4O3)065j3,0N1b0_0+4^5u2t0f3o5M484w0+1b0g2x0z0v0p2%4Y5N1 1a040I5R4}3T5V0v0}1{5,4D5(1b0)0-3)0R5}5t5S3j1b0{5;0z5b5%165w5y3c5 5-3H0t1b2H5?3G5)5+5$604~040g5:0W5=6m6d5)0)5|5~5A6104350n0x0z6s655z670169666n5.6p6r1{0G3J0z5!0i0L2!6i3,6k6!4g620|6H6%4n5)0k6N6d5C045h3e6K6w5E5~6c5@165I040+3.6:6~3H1b0L743G0i5P0433793,0b6f045Z0b5W6,2t6$6u750b6)647n5^045`6y6|5}6A1 70720v7f6(040B7H5v7c7e6J6O6e1b7k7m7q6j1b6l6^7Q7s04636+7V6#5_5{5i7A7.6}3G700L5L7P6d7#6q7u7)495)0w7v6P787}6-1b0m80846B7K897w0m7L2t696a3s7:7g4 515r6b7C687c2n0H8f6o0x6X2T0b0u0G0x1$2n0Z1I8c167p7Z7_5/7|8L756.8v8281018R7^7r1b8b8P7W7x8S6L598i3D8k5d5f044I8#7*047,3c067/8{8-4w1b6D6F7(8=7~1b88938~7d8U5)878U7#8!4@6_868(6M8X5k045m5o5q7z8|8q01706G7?8(7`6R6I977o959d779a86969g7!8Z9H048e9l578*9y5l5n5p8o8j9t7b1b8t8(6=4z8p6K5w020W0Z0Q8+2*8}6B8x0L8z8B8D0x8F8H9C7w7Y9K8M6Q8Oa38Q1b6/9Q7I83a08Ja99T7J9N6xab5v1b9-9/9;3L9t6=8;a78$8^4t8|7/9t7#906G6tae8V9E8I7699aJ9b9J3DaB9MaM9ial8g59ah9o9W9r9t702!0Z0n0v0bahaD924t1J4`4=4Za=0!4$1J0Z4(a`2:2,2a2c2.0p1`a@4$1P4|752!0d0G0+0p0N0z0G0,0(1b1B1D1F1H0RaxaP1W3t1Q0X0W0R1H0Z0R0H0/0u439_0R2R140Lb4bA1|0y3J0y0n1{0vbA7?0+0/2!0b0Zbo0g0/0bbW5!0L1s0 1f0y0y1H2T6F0 0H0n0R0B0zb^2X120R8D0z0#1Sbt040e1t392Q2S1|2Ra)106G0p0Rb~720b2$b*1t4_4,7Jb{0G0_0G128C0L6Ia;3L0y0L0C0_140i0n0 7,1Z4.2 49211/1;1?b83G2G2x2z1b2M0E0y5:0?bz0h0M2h1s4^4;b83d4@cza#5J0z7@aG7c55aJ0b5Ucq0ncsbgcvc09Na2aP6K9za6d77Q8W9*9L6C0t0G5W2`5Z2V9 av8?7y7-6z6K7E73aU6o0G9j7Na+dw3T7i7T9Bdo945*9Fdgdi5Xdlcmdndb6v7+9r6|aQa5a.8,9ZaWdCaKdj5Yb)c+aSdJc|8NdY2*9t6`5ia:cpa?2+b61U040J000/1#bZcd8D1f3J9_d*2Wb|0/0t1qbLch000z0K5YcBb/2jbYcxbYbA003.bo0`bA0/0B0UbG1p2Tb{0v0 4+c}1-a)e90 330ZbWb:8F1H0#060ScG0 cc6F0A0Rba0?12b/bS1{2j2X2me)000n2Weuej1x1{eFcCcEbDcHbpc31!1$3GcO231=2B7QcU2I2K0E2/0n2$a)bo0u261Hc,4!3e4Yc;6K0y0D1b031A0/0g125Wb?1|0W002n0L1i5#8_dW0c0*0X0J0J0$0G0j0$fM0qfN9jd#de6;8/4XfHd81b0@fRfK0G0E0$0j0e0=f(0EfV5x9%c~0O0#9)a/f$04f.fT0$0q0o0GaY5q0$f?aq9?1 0u2q0401030:0z0T0l0y2q5E9tfqfsfufw0pfybAb^b`0n4l9mfJfLfUd$9kfX759(f|4BdW7{d:ar9+fW9Yf~gN6Sei1Ce$dGdRa8d-aGgd1b01fhb3e^01ajgA8ldLd(dOb+g99%fZ6@4t5G49gq04ft12ck1C2xbzb@b_b{g:7Ie50ne70ue9d5dKgUgZd;9h04aagH9m7hdMdkeKg/d@0!c;1W4!a^4/f0cM4nf3cQf66df8cW040r3.0W0i7U3ec-3@c/aPfo7Qh0ft0ofvfxbob}fC0bfEhhd@f~gCfMfOfQfSgEhq9Rf@d$6=f!f}dff(0Jf*f,f.f:0$f=gFgRdZ6K0df_f{hb98g0fNg3g59Vg7g_d$g(gfghgjglgn5ig~4nh!gsh(b?gxhah/dfh;h_gS7QgGiKfY1b0Pg|gLgT9Aiph`7Ihk0GgWe@hlcS8?d6hm7Qir20hPhR2Ahwf#dfhsg?hviah|iW5Bg{gofpfrh1ch2nb/2Jeqh8gyih9@9_he1:hgfGdH85g$jh6Bhk9NhpiN8Yg=dNi_aGd?fHhyd_hAb5hDcLf21;f4cR9thL2J1b0%b$b(e3bS2X9}9_0u6Vgz4YhUfm3ehY6diAh$gtgvh*fDfFcmja6oiIh?fR0Jg1iVjp3Gh~j.6Pi2i4f-f/f;j^ic7Qie5g0#4ri=a4ijg2g4g60cg8i`ga9ti,itgkgmg.ixgpj1h#h%guh)iEjVkajqj:k39=as8/4jiR4KiTdakDgQi{j_g;iYi!gYhiaJi,jR14jU0Kkpju5_j|aKi@jsdmkCgPk58/iQkH1ciy2tiAh3j5h6gwh9kyi0a4hdhfh.k#jjg!9mjmd,jok4a4k)huk+d,akjwhzhUhC0x3ta^0`6*0u04.

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

.128013nTmOwgPoC,6]uRaUH8bsr[vcezj-1S9_d(Lxiyk02; V5àMlI4t/.EG3)Afh:=é7qNpD050H0z0Z0p0L0W0u0R0y0W0p0u0u0.010Z0L0?010406050u0n0d0d0p0v0M040E0i0W0n180i0b0R020p0d0?0Q0R0o0z1i0v0;0n0z0u050!1f1h1j1l1d0?041J1Q051T0!1T1V1Q1d0H0L0x101214160,0L0g0,0W1-0,0Z1b050{0t0W0z1(1315011,1.1:1.0Z1_1{1@0Z0t0i0H1l1^0v1R0Z0,101o0u0?0p0b160P011}1*010+0}0z0b1w0z1@2l2n2s1 2v1{2y0d2A040a0R0h0v0i0?0i0u0L1r1t0_2j0v0v0z0y2V1J2C0b1R0!2h2+0Z2f2e2g0H2E161:0b2x2S1@1#1%111~2^0L2`0b2b1$1@0?2!1R2)2+3c1e2m1t302t350v1i0W1b0R0D2(3g1c3f2D3i1 3k3m3o0P3r2n3t2)2@013y0p3n040R0(3C2*1d3F3w163I3K0R0Y3O3E3g3G3U3o0T3Y3Q3!3S3H0i3l3J3o0l3)3u3h1)3x3.3z3L0:3?3R3_3T3{3:3L0s3 3+413-3/3V0F473v493$040D0O4e3^314a3|0D3q1K3s3*4f4n4h0D3B4s3D4u4m3j433K0D3N4A3P3@3#4F1b0D3X4J3Z4v4E4b4O3(4R1S3a1J2~2.0H2=3G0y2b2K0^1$1R390z3b3s3Y054+0_4?4T3x1b0V0e0o0c3Y0R4L3,0i1b0.5456490d0L1b4k4R4C3#1b0S0X0S0*0=534R55404n58045a5s5c4n5e4O3)065j3,0N1b0_0+4^5u2t0f3o5M484w0+1b0g2x0z0v0p2%4Y5N1 1a040I5R4}3T5V0v0}1{5,4D5(1b0)0-3)0R5}5t5S3j1b0{5;0z5b5%165w5y3c5 5-3H0t1b2H5?3G5)5+5$604~040g5:0W5=6m6d5)0)5|5~5A6104350n0x0z6s655z670169666n5.6p6r1{0G3J0z5!0i0L2!6i3,6k6!4g620|6H6%4n5)0k6N6d5C045h3e6K6w5E5~6c5@165I040+3.6:6~3H1b0L743G0i5P0433793,0b6f045Z0b5W6,2t6$6u750b6)647n5^045`6y6|5}6A1 70720v7f6(040B7H5v7c7e6J6O6e1b7k7m7q6j1b6l6^7Q7s04636+7V6#5_5{5i7A7.6}3G700L5L7P6d7#6q7u7)495)0w7v6P787}6-1b0m80846B7K897w0m7L2t696a3s7:7g4 515r6b7C687c2n0H8f6o0x6X2T0b0u0G0x1$2n0Z1I8c167p7Z7_5/7|8L756.8v8281018R7^7r1b8b8P7W7x8S6L598i3D8k5d5f044I8#7*047,3c067/8{8-4w1b6D6F7(8=7~1b88938~7d8U5)878U7#8!4@6_868(6M8X5k045m5o5q7z8|8q01706G7?8(7`6R6I977o959d779a86969g7!8Z9H048e9l578*9y5l5n5p8o8j9t7b1b8t8(6=4z8p6K5w020W0Z0Q8+2*8}6B8x0L8z8B8D0x8F8H9C7w7Y9K8M6Q8Oa38Q1b6/9Q7I83a08Ja99T7J9N6xab5v1b9-9/9;3L9t6=8;a78$8^4t8|7/9t7#906G6tae8V9E8I7699aJ9b9J3DaB9MaM9ial8g59ah9o9W9r9t702!0Z0n0v0bahaD924t1J4`4=4Za=0!4$1J0Z4(a`2:2,2a2c2.0p1`a@4$1P4|752!0d0G0+0p0N0z0G0,0(1b1B1D1F1H0RaxaP1W3t1Q0X0W0R1H0Z0R0H0/0u439_0R2R140Lb4bA1|0y3J0y0n1{0vbA7?0+0/2!0b0Zbo0g0/0bbW5!0L1s0 1f0y0y1H2T6F0 0H0n0R0B0zb^2X120R8D0z0#1Sbt040e1t392Q2S1|2Ra)106G0p0Rb~720b2$b*1t4_4,7Jb{0G0_0G128C0L6Ia;3L0y0L0C0_140i0n0 7,1Z4.2 49211/1;1?b83G2G2x2z1b2M0E0y5:0?bz0h0M2h1s4^4;b83d4@cza#5J0z7@aG7c55aJ0b5Ucq0ncsbgcvc09Na2aP6K9za6d77Q8W9*9L6C0t0G5W2`5Z2V9 av8?7y7-6z6K7E73aU6o0G9j7Na+dw3T7i7T9Bdo945*9Fdgdi5Xdlcmdndb6v7+9r6|aQa5a.8,9ZaWdCaKdj5Yb)c+aSdJc|8NdY2*9t6`5ia:cpa?2+b61U040J000/1#bZcd8D1f3J9_d*2Wb|0/0t1qbLch000z0K5YcBb/2jbYcxbYbA003.bo0`bA0/0B0UbG1p2Tb{0v0 4+c}1-a)e90 330ZbWb:8F1H0#060ScG0 cc6F0A0Rba0?12b/bS1{2j2X2me)000n2Weuej1x1{eFcCcEbDcHbpc31!1$3GcO231=2B7QcU2I2K0E2/0n2$a)bo0u261Hc,4!3e4Yc;6K0y0D1b031A0/0g125Wb?1|0W002n0L1i5#8_dW0c0*0X0J0J0$0G0j0$fM0qfN9jd#de6;8/4XfHd81b0@fRfK0G0E0$0j0e0=f(0EfV5x9%c~0O0#9)a/f$04f.fT0$0q0o0GaY5q0$f?aq9?1 0u2q0401030:0z0T0l0y2q5E9tfqfsfufw0pfybAb^b`0n4l9mfJfLfUd$9kfX759(f|4BdW7{d:ar9+fW9Yf~gN6Sei1Ce$dGdRa8d-aGgd1b01fhb3e^01ajgA8ldLd(dOb+g99%fZ6@4t5G49gq04ft12ck1C2xbzb@b_b{g:7Ie50ne70ue9d5dKgUgZd;9h04aagH9m7hdMdkeKg/d@0!c;1W4!a^4/f0cM4nf3cQf66df8cW040r3.0W0i7U3ec-3@c/aPfo7Qh0ft0ofvfxbob}fC0bfEhhd@f~gCfMfOfQfSgEhq9Rf@d$6=f!f}dff(0Jf*f,f.f:0$f=gFgRdZ6K0df_f{hb98g0fNg3g59Vg7g_d$g(gfghgjglgn5ig~4nh!gsh(b?gxhah/dfh;h_gS7QgGiKfY1b0Pg|gLgT9Aiph`7Ihk0GgWe@hlcS8?d6hm7Qir20hPhR2Ahwf#dfhsg?hviah|iW5Bg{gofpfrh1ch2nb/2Jeqh8gyih9@9_he1:hgfGdH85g$jh6Bhk9NhpiN8Yg=dNi_aGd?fHhyd_hAb5hDcLf21;f4cR9thL2J1b0%b$b(e3bS2X9}9_0u6Vgz4YhUfm3ehY6diAh$gtgvh*fDfFcmja6oiIh?fR0Jg1iVjp3Gh~j.6Pi2i4f-f/f;j^ic7Qie5g0#4ri=a4ijg2g4g60cg8i`ga9ti,itgkgmg.ixgpj1h#h%guh)iEjVkajqj:k39=as8/4jiR4KiTdakDgQi{j_g;iYi!gYhiaJi,jR14jU0Kkpju5_j|aKi@jsdmkCgPk58/iQkH1ciy2tiAh3j5h6gwh9kyi0a4hdhfh.k#jjg!9mjmd,jok4a4k)huk+d,akjwhzhUhC0x3ta^0`6*0u04.

  1. il a ainsi été montré que le jeu de la vie est Turing-complet