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

.128013bVeOn,49vi[+3mo5tR;PhkMjlpTNwf(: cg.a=ry0S6I]-u/72)As18d050(0d0r0L0k0z0#0H0I0z0L0#0#0M010r0k0A010406050#0V0o0o0L0N0O040Q0p0z0V0|0p0f050W13151719110A04051p1i1s0W1p110(0k0j0;0?0^0`0v0k0J0v0z1G0v0r0 050,0b0z0d1B0@0_011F1H1J1H0r1P1R1N0r0N1q0r0v0;1c0#0A0L0f0`0Y011T1D010E0.0d0f0L0o0d1N1:1=1`1V1}1R20220 0a0H0u0N0p0A0p0#0k1f0f0H0*1.0N0N0d0I2n1i250f1q0W1,2A1)1+1*1O0(270`1J0f1 2k1N1y1A0=1U2K0k2M0f0p2Q1N0A2t1q2y2A2(121;2o2S1{2X0N160z0 0H0$2x2,102+262.1V2:2=2@0Y2`1=2|2y2J01310L2?040H0n352z11382 0`3b3d0H0h3h372,393n2@0q3r3j3t3l3a0p2;3c2@0R3y2}2-1C303D323e0X3I3k3L3m3N3F3e0%3R3A3T3C3E3o0i3Z2~3#3v040$0P3*3K2T3$3O0$2_1j2{3z3+3?3-0$343{363}3=2/3V3d0$3g432z1t2$1i2Q2D0(1+2I3B0I2Y231q4h1r4f2*4c1q4n0*2%3!3 0 0x0e0s0B3r0H3J390p0 0M4H4J3B0o0k0 3:4v453u0 0c0S0c0!0C4G4v4I3S3?4L044N4)4P3#4R0 3`2(064`4;3?0w0 0*0E3r4|1{0D2@524+2/0E0 0j0p0k2l0f0#574A1{0~040F5i3~2/0 0J0N0.1R5o461V5l0g4O58300 0k5w395z5B5j5D040y5G3B5l0Z0G3y0H5U4*5K3m0 0,5u0d5J5p1V4-4/2(5W5(3m0b0 2a5O3#5l5n4v535L5s5#5?3?5Q3y065V5-5x5Y041y2t2v0k1g5h4:5C0`5*5%66015^5_2*6g014-0U5 1{4?3.6t5y0 5A6f5X6q0 6s5`6p6v4^2{5{0`5Q6A5,6L6l0 6n6K6p6r6x0`6I6X6R046O2{65396v4U6o6C6N6j5H6S6!6W6G6C6Z6^5.6#6%366)4Q4S6w6{6k6/6B6|5^6!6+6!5I776k6@6-6|6`7h750 0Z6~2z705@6=746*726,6U6.6z6:714@7c7m7o3e6Q797t7B737k6;6$7A3#7g7x7i726J367H7E7P607s7M7K7V4d6p7d6P6H7v7D047n7Z5k7#7S6k7j7^7N7F7q3?7`7W7*7m0Z5T5V6Q0f0 2t130z0,0r7=5)4M8f6M0 0l0T855U6Q4~040E3D8i3a4 5F7J7r7O7e4X685N8B3B0p55042V8u88680k6a2n6e7$8z5S4V64648p5E518F4=7.8#4,0 028c0t5+6(875E8u4-0m8L8w8=8*8,8^045!0z5v8(1{8H0 1=0(8u7b928g048+0r8-8}8E7,6C8?8}0(9h8/6V8{9e8}8 918S7!048U4_8W9A7~5q048a0V8c0L8e8y8)040K6!8M0L0A0A1 979K7?5m6T816C8M8x9i6|9k9a671y7/7}8:5M8`048@9*8v8D7/0Z848V866p8q2t0r0V0N1h9@8M9F9H9J4_1i4x0d2A2#ae4g1z4i2D2G2B0L1Qah0W4h11ar0+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

.128013bVeOn,49vi[+3mo5tR;PhkMjlpTNwf(: cg.a=ry0S6I]-u/72)As18d050(0d0r0L0k0z0#0H0I0z0L0#0#0M010r0k0A010406050#0V0o0o0L0N0O040Q0p0z0V0|0p0f050W13151719110A04051p1i1s0W1p110(0k0j0;0?0^0`0v0k0J0v0z1G0v0r0 050,0b0z0d1B0@0_011F1H1J1H0r1P1R1N0r0N1q0r0v0;1c0#0A0L0f0`0Y011T1D010E0.0d0f0L0o0d1N1:1=1`1V1}1R20220 0a0H0u0N0p0A0p0#0k1f0f0H0*1.0N0N0d0I2n1i250f1q0W1,2A1)1+1*1O0(270`1J0f1 2k1N1y1A0=1U2K0k2M0f0p2Q1N0A2t1q2y2A2(121;2o2S1{2X0N160z0 0H0$2x2,102+262.1V2:2=2@0Y2`1=2|2y2J01310L2?040H0n352z11382 0`3b3d0H0h3h372,393n2@0q3r3j3t3l3a0p2;3c2@0R3y2}2-1C303D323e0X3I3k3L3m3N3F3e0%3R3A3T3C3E3o0i3Z2~3#3v040$0P3*3K2T3$3O0$2_1j2{3z3+3?3-0$343{363}3=2/3V3d0$3g432z1t2$1i2Q2D0(1+2I3B0I2Y231q4h1r4f2*4c1q4n0*2%3!3 0 0x0e0s0B3r0H3J390p0 0M4H4J3B0o0k0 3:4v453u0 0c0S0c0!0C4G4v4I3S3?4L044N4)4P3#4R0 3`2(064`4;3?0w0 0*0E3r4|1{0D2@524+2/0E0 0j0p0k2l0f0#574A1{0~040F5i3~2/0 0J0N0.1R5o461V5l0g4O58300 0k5w395z5B5j5D040y5G3B5l0Z0G3y0H5U4*5K3m0 0,5u0d5J5p1V4-4/2(5W5(3m0b0 2a5O3#5l5n4v535L5s5#5?3?5Q3y065V5-5x5Y041y2t2v0k1g5h4:5C0`5*5%66015^5_2*6g014-0U5 1{4?3.6t5y0 5A6f5X6q0 6s5`6p6v4^2{5{0`5Q6A5,6L6l0 6n6K6p6r6x0`6I6X6R046O2{65396v4U6o6C6N6j5H6S6!6W6G6C6Z6^5.6#6%366)4Q4S6w6{6k6/6B6|5^6!6+6!5I776k6@6-6|6`7h750 0Z6~2z705@6=746*726,6U6.6z6:714@7c7m7o3e6Q797t7B737k6;6$7A3#7g7x7i726J367H7E7P607s7M7K7V4d6p7d6P6H7v7D047n7Z5k7#7S6k7j7^7N7F7q3?7`7W7*7m0Z5T5V6Q0f0 2t130z0,0r7=5)4M8f6M0 0l0T855U6Q4~040E3D8i3a4 5F7J7r7O7e4X685N8B3B0p55042V8u88680k6a2n6e7$8z5S4V64648p5E518F4=7.8#4,0 028c0t5+6(875E8u4-0m8L8w8=8*8,8^045!0z5v8(1{8H0 1=0(8u7b928g048+0r8-8}8E7,6C8?8}0(9h8/6V8{9e8}8 918S7!048U4_8W9A7~5q048a0V8c0L8e8y8)040K6!8M0L0A0A1 979K7?5m6T816C8M8x9i6|9k9a671y7/7}8:5M8`048@9*8v8D7/0Z848V866p8q2t0r0V0N1h9@8M9F9H9J4_1i4x0d2A2#ae4g1z4i2D2G2B0L1Qah0W4h11ar0+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

.128013bVeOn,49vi+[3mo5_tRPhkMjlpTNwf(: cga=ry0S6I]u/72)As18d050$0d0s0K0k0z0Z0H0I0z0K0Z0Z0L010s0k0A010406050Z0T0o0o0K0M0N040P0p0z0T0`0p0f050U111315170 0A04051n1g1q0U1n0 0$0k0j0/0;0?0^0v0k0J0v0z1E0v0s0}050*0b0z0d1z0=0@011D1F1H1F0s1N1P1L0s0M1o0s0v0/1a0Z0A0K0f0^0W011R1B010E0,0d0f0K0o0d1L1.1:1^1T1{1P1~200}0a0H0u0M0p0A0p0Z0k1d0f0H0(1,0M0M0d0I2l1g230f1o0U1*2y1%1)1(1M0$250^1H0f1}2i1L1w1y0:1S2I0k2K0f0p2O1L0A2r1o2w2y2$101/2m2Q1_2V0M140z0}0!2v2*0~2)242,1T2.2:0}0W2@1:2_2w2H012~0K2;040n322x0 352|0^383a0h3d342*363j0}0q3m3f3o3h370p2/390}0Q3t2`2+1A2}3y2 040V3D3g3G3i3I3A040#3M3v3O3x3z3a0i3m1r2!1g2O2B0$1)2G3w0I2W211o3)1p3%2(1h2^053/0(2#3V2R370}0x0e0t0B3m0H3E360p0}0L484a3w0o0k0}0O3U2{3W0f0}0c0R0c0Y0C473`33493N414c044e4x2x4z401_4i2=3t063u4n410w0}0(0E3#4A1_0D0}494F3 4P2-0E0}0j0p0k2j0f0Z0r0j1x1:0s0Z4V4I1T0|040F4`4%2}0}0J0M0,1P503F414}0g4f4W52040k58365b5d4{3i0}0y5i3w4}0X0G3t0H5w4H515n040s0p0*0z5l5z014C4E2$5y594J4j044l4#065x5M364R040E3y5G5N5f0k4;4,4.5q3W5k4#5V3w4p040y5)4-2T5#4b4Y5g1f5/4g4o4*5*2T4_4#615a0}4 675e5A54560d5,69045c606d425g6i1_5.5L682-5o6q4|0}5t5v5U5x6u5f5C5E5{3w4C0l5K2^5:62046f0z576c5m014}0m6x5A5(4+5_5 2(6n4}0S6Y6U5H5=5@6$5+6.5$0^6+6B5w6E0^5X2r0s0T0M6(6N6}6o6G393D0U3}0d2y2Z7d3(1x3*2B2E2z0K1O7g0U3)0 7q0)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

.128013bVeOn,49vi+[3mo5_tRPhkMjlpTNwf(: cga=ry0S6I]u/72)As18d050$0d0s0K0k0z0Z0H0I0z0K0Z0Z0L010s0k0A010406050Z0T0o0o0K0M0N040P0p0z0T0`0p0f050U111315170 0A04051n1g1q0U1n0 0$0k0j0/0;0?0^0v0k0J0v0z1E0v0s0}050*0b0z0d1z0=0@011D1F1H1F0s1N1P1L0s0M1o0s0v0/1a0Z0A0K0f0^0W011R1B010E0,0d0f0K0o0d1L1.1:1^1T1{1P1~200}0a0H0u0M0p0A0p0Z0k1d0f0H0(1,0M0M0d0I2l1g230f1o0U1*2y1%1)1(1M0$250^1H0f1}2i1L1w1y0:1S2I0k2K0f0p2O1L0A2r1o2w2y2$101/2m2Q1_2V0M140z0}0!2v2*0~2)242,1T2.2:0}0W2@1:2_2w2H012~0K2;040n322x0 352|0^383a0h3d342*363j0}0q3m3f3o3h370p2/390}0Q3t2`2+1A2}3y2 040V3D3g3G3i3I3A040#3M3v3O3x3z3a0i3m1r2!1g2O2B0$1)2G3w0I2W211o3)1p3%2(1h2^053/0(2#3V2R370}0x0e0t0B3m0H3E360p0}0L484a3w0o0k0}0O3U2{3W0f0}0c0R0c0Y0C473`33493N414c044e4x2x4z401_4i2=3t063u4n410w0}0(0E3#4A1_0D0}494F3 4P2-0E0}0j0p0k2j0f0Z0r0j1x1:0s0Z4V4I1T0|040F4`4%2}0}0J0M0,1P503F414}0g4f4W52040k58365b5d4{3i0}0y5i3w4}0X0G3t0H5w4H515n040s0p0*0z5l5z014C4E2$5y594J4j044l4#065x5M364R040E3y5G5N5f0k4;4,4.5q3W5k4#5V3w4p040y5)4-2T5#4b4Y5g1f5/4g4o4*5*2T4_4#615a0}4 675e5A54560d5,69045c606d425g6i1_5.5L682-5o6q4|0}5t5v5U5x6u5f5C5E5{3w4C0l5K2^5:62046f0z576c5m014}0m6x5A5(4+5_5 2(6n4}0S6Y6U5H5=5@6$5+6.5$0^6+6B5w6E0^5X2r0s0T0M6(6N6}6o6G393D0U3}0d2y2Z7d3(1x3*2B2E2z0K1O7g0U3)0 7q0)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

.128013bqO,9vià3o_x;GHMjlpTwf( g0]6-)2As18Vené4[Em5tCLRPhkN:c.a=ryDzSIu/7Ud050@0L0T0(0h0s0H0y0$0s0(0H0H0)010T0h0t010406050H0:0R0R0(0*0+040.0k0s0:180k0M0y020(0R0t0n0y0W0L1i0*0c0:0L0H050;1f1h1j1l1d0t04051Q1J1T0;1Q1d0@0h0g101214160Y0h0z0Y0s1+0Y0T1b050{0b0s0L1$1315011*1,1.1,0T1@1_1=0T0*1R0T0Y101o0H0t0(0M160F011{1(010w0}0L0M1w0L1=2e2g2l1}2o1_2r0R2t040a0y0X0*0k0t0k0H0h1r1t0_2c0*0*0L0$2O1J2v0M1R0;2a2!2729281?0@2x161.0M2q2L1=1Z1#111|2.0h2:0M0k2@1=0t2T1R2Y2!351e2f1t2_2m2~0*1i0s1b0y0I2X391c382w3b1}3d3f3h0F3k2g3m2Y2-013r0(3g040y0j3v2Z1d3y3p163B3D0y0O3H3x393z3N3h0S3R3J3T3L3A0k3e3C3h0C3Y3n3a1%3q3%3s3E0=3,3K3/3M3;3)3E0J3^3!3`3$3(3O0f403o423V040I0A473.2`433=0I3j1K3l3Z484g4a0I3u4l3w4n4f3c3|3D0I3G4t3I3-3U4y1b0I3Q4C3S4o4x444H3X4K1U331J2@2%0@292,3#0$2 2D0^1!1R320L343l3R054#0_4-4M3q1b0q0d0W0u3R0y4E3#0k1b0)4~50420R0h1b4d4K4v3U1b0K0/0K0G0!4}4K4 3_4g5204545m564g584H3Y065d3#0Z1b0_0w4/5o2m0v3h5G414p0w1b0z2q0L0*0(2W4R5H1}1a040x5L4@3M5P0*0}1_5$4w5Y1b0E0#3Y0y5@5n5M3c1b0{5+0L555X165q5s355_5%3A0b1b2A5-3z5Z5#5W5`4^040z5*0s5,6g675Z0E5?5^5u5{042~0:0g0L6m5 5t610163606h5(6j6l1_0l3C0L5U0k0h2T6c3#6e6U495|0|6B6X4g5Z0e6H675w045b376E6q5y5^665.165C040w3%6*6^3A1b0h6~3z0k5J042|733#0M69045T0M5Q6$2m6W6o6 0M6Z5~7h5/045;6s6?5@6u1}6`6|0*796Y040r7B5p76786D6I681b7e7g7k6d1b6f6/7K7m045}6#7P6V5:5=5c7u7(6@3z6`0h5F7J677V6k7o7Z425Z0P7p6J727@6%1b0B7`7~6v7E837q0B7F2m63643l7*7a4_4{5l657w62762g0@896i0g6R2M0M0H0l0g1!2g0T1I86167j7T7:5)7?8F6 6(8p7|7{018L7/7l1b858J7Q7r8M6F538c3w8e5759044B8V7!047$35067)8=8%4p1b6x6z7Y8,7^1b828}8^778O5Z818O7V8U4.6:808Y6G8R5e045g5i5k7t8?8k016`6A7-8Y7;6L6C917i8 97719480909a7U8T9B04889f518!9s5f5h5j8i8d9n751b8n8Y6,4s8j6E5q020s0T0n8#2Z8@6v8r0h8t8v8x0g8z8B9w7q7S9E8G6K8I9}8K1b6)9K7C7}9`8Da39N7D9H6ra55p1b9%9)9+3E9n6,8+a18W8/4m8?7)9n7V8`6A6na88P9y8C7093aD959D3wav9GaG9caf8a53ab9i9Q9l9n6`2T0T0:0*0Mabax8|4m1J4;4,4Sa,0;4V1J0T4Xa;2*2#0(1^a.4V1P4?6 2T0R0l0w0(0Z0L0l0Y0j1b1B1D1F1H0yaraJ1W3m1Q0/0s0y1H0T0y0@0N0H3|9:0y2K140ha{br1`0$3C0$0:1_0*br7-0w0N2T0M0Tbf0z0N0MbN5U0h1s0 1f0$0$1H2M6z0 0@0:0y0r0Lb,2Q120y8x0L0%1Ubk040d1t322J2L1`2KaZ106A0(0yb=6|0M2VbX1t4:4$7Db/0l0_0l128w0h6Ca+3E0$0h0D0_140k0:0 7$1X4(2^421 1-1/1;a 3z2z2q2s1b2F0.0$5*0tbq0X0+2a1s4/4+a 364.cqaV5D0L7.aA764 aD0M5Och0:cjb7cmb@9H9|aJ6E9ta0c~7K8Q9!9F6w0b0l5Q2:5T2O9_ap8-7s7%6t6E7y6}aO6i0l9d7Ha#dn3M7c7N9vdf8~5!9zd7d95Rdccdded26p7#9l6?aK9 a(8$9TaQdtaEda5SbWcYaMdAc:8HdP2Z9n6;5ca*cga-2!a}1S040V000N1ZbQc48x1f3C9:dX2Pb:0N0b1qbCc8000L0m5Scsb$2cbPcobPbr003%bf0`br0N0r0ibx1p2Mb/0*0 4#c;1+aZe00 2|0TbNb%8z1H0%060Kcx0 c36z0-0yb10t12b$bJ1_2c2Q2feW000:2Pelea1x1_ewctcvbucybgb`1Y1!3zcF211:2u7KcL2B2D0.270:2VaZbf0H241HcZ4T374Rc(6E0$0I1b031A0N0z125Qb*1`0s02030j0f0n2g0h1i5V8:dN0u0G0/0V0V0Q0l0U0QfH0?fI9ddSd56+8)4QfCc 1b0,fMfF0l0.0Q0U0d0!fZ0.fQ5r9Xc=0A0%9Za)fX04f)fO0Q0?0W0laS5k0Qf.ak9-1}0H2j04021F0k9)030=0L0S0C0$0Fgb0:gd0n5y9nfhfjflfn0(fpbrb,b.0:4e9gfEfGfPdT9efS6 9Yf@4udN7=d%al9#fR9Sf_gP6Me91CeTdxdIa2d!aAg8ahgc9)f8a`e,gmgoadgC8fdCdVdFbYg49XfU6.4m5A42gs04fk12cb1C2qbqb+b-b/g@7Cd|0:d~0He0c|dBgWg#d(9b04a4gJ9g7bdDdbeBg?d+0;c(1W4Ta/4)e@cD4ge`cHe}67e cN040p3%0s0k7O37c!3-c$aJff7Kh4fk0Wfmfobfb;ftfvfx0Mfzhld+f_gEfHfJfLfNgGhu9Lf/dT6,fVf^d6fZ0Vf#f%f)f+0Qf-gHgTdQ6E0Rf;f?hf92f{fIf~g09Pg2g}dTg*gag,0ngfghgjglizgqfgfih5guh,b*gzheh^d6h`h gU7KgIiTfT1b0Fh0gNgV9uivi07Cho0lgYe+hpcJ8-c}hq7Kixg;9)0YhThV0Li_gpdZaefWd6hwg`hzigi2i)5vg iGh%iIh62gb$2CehhcgAin9.9:hi1.hkfBdy7 g(ju6vho9HhtiW8Sg_dEj7aAd*fChCd-hEa|hHcCe_1/e{cI9nhP2C1b0obTbVd`bJ2Q9@9:0H6PgB4RhYfd37h$67h(iKgwh-frh/fwfyfAcdjn6iiRh|fM0Vf|i(jC3zi4k06Ji8iaf(f*f,k7ii7Kik5a0%4kj39~ipf}f g10ug3j8g59ni^iziBgigki jdj=jfj@gxjliOkpjDk2ki9,am8)4ci!4Di$d1kRgSj9k8g^i+i-g!hmaDkAgn9)j(14j+0mkFj1kbaEj5jFddkQgRkk8)iZkV1ch24gj?h7jihagyhdj,kN9ghhhjh@jH7Rhni%dZjBkj9~k{hyk}k^hBhDhYhG0g3ma/0`6!0H04.

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

.128013bqO,9vià3o_x;GHMjlpTwf( g0]6-)2As18Vené4[Em5tCLRPhkN:c.a=ryDzSIu/7Ud050@0L0T0(0h0s0H0y0$0s0(0H0H0)010T0h0t010406050H0:0R0R0(0*0+040.0k0s0:180k0M0y020(0R0t0n0y0W0L1i0*0c0:0L0H050;1f1h1j1l1d0t04051Q1J1T0;1Q1d0@0h0g101214160Y0h0z0Y0s1+0Y0T1b050{0b0s0L1$1315011*1,1.1,0T1@1_1=0T0*1R0T0Y101o0H0t0(0M160F011{1(010w0}0L0M1w0L1=2e2g2l1}2o1_2r0R2t040a0y0X0*0k0t0k0H0h1r1t0_2c0*0*0L0$2O1J2v0M1R0;2a2!2729281?0@2x161.0M2q2L1=1Z1#111|2.0h2:0M0k2@1=0t2T1R2Y2!351e2f1t2_2m2~0*1i0s1b0y0I2X391c382w3b1}3d3f3h0F3k2g3m2Y2-013r0(3g040y0j3v2Z1d3y3p163B3D0y0O3H3x393z3N3h0S3R3J3T3L3A0k3e3C3h0C3Y3n3a1%3q3%3s3E0=3,3K3/3M3;3)3E0J3^3!3`3$3(3O0f403o423V040I0A473.2`433=0I3j1K3l3Z484g4a0I3u4l3w4n4f3c3|3D0I3G4t3I3-3U4y1b0I3Q4C3S4o4x444H3X4K1U331J2@2%0@292,3#0$2 2D0^1!1R320L343l3R054#0_4-4M3q1b0q0d0W0u3R0y4E3#0k1b0)4~50420R0h1b4d4K4v3U1b0K0/0K0G0!4}4K4 3_4g5204545m564g584H3Y065d3#0Z1b0_0w4/5o2m0v3h5G414p0w1b0z2q0L0*0(2W4R5H1}1a040x5L4@3M5P0*0}1_5$4w5Y1b0E0#3Y0y5@5n5M3c1b0{5+0L555X165q5s355_5%3A0b1b2A5-3z5Z5#5W5`4^040z5*0s5,6g675Z0E5?5^5u5{042~0:0g0L6m5 5t610163606h5(6j6l1_0l3C0L5U0k0h2T6c3#6e6U495|0|6B6X4g5Z0e6H675w045b376E6q5y5^665.165C040w3%6*6^3A1b0h6~3z0k5J042|733#0M69045T0M5Q6$2m6W6o6 0M6Z5~7h5/045;6s6?5@6u1}6`6|0*796Y040r7B5p76786D6I681b7e7g7k6d1b6f6/7K7m045}6#7P6V5:5=5c7u7(6@3z6`0h5F7J677V6k7o7Z425Z0P7p6J727@6%1b0B7`7~6v7E837q0B7F2m63643l7*7a4_4{5l657w62762g0@896i0g6R2M0M0H0l0g1!2g0T1I86167j7T7:5)7?8F6 6(8p7|7{018L7/7l1b858J7Q7r8M6F538c3w8e5759044B8V7!047$35067)8=8%4p1b6x6z7Y8,7^1b828}8^778O5Z818O7V8U4.6:808Y6G8R5e045g5i5k7t8?8k016`6A7-8Y7;6L6C917i8 97719480909a7U8T9B04889f518!9s5f5h5j8i8d9n751b8n8Y6,4s8j6E5q020s0T0n8#2Z8@6v8r0h8t8v8x0g8z8B9w7q7S9E8G6K8I9}8K1b6)9K7C7}9`8Da39N7D9H6ra55p1b9%9)9+3E9n6,8+a18W8/4m8?7)9n7V8`6A6na88P9y8C7093aD959D3wav9GaG9caf8a53ab9i9Q9l9n6`2T0T0:0*0Mabax8|4m1J4;4,4Sa,0;4V1J0T4Xa;2*2#0(1^a.4V1P4?6 2T0R0l0w0(0Z0L0l0Y0j1b1B1D1F1H0yaraJ1W3m1Q0/0s0y1H0T0y0@0N0H3|9:0y2K140ha{br1`0$3C0$0:1_0*br7-0w0N2T0M0Tbf0z0N0MbN5U0h1s0 1f0$0$1H2M6z0 0@0:0y0r0Lb,2Q120y8x0L0%1Ubk040d1t322J2L1`2KaZ106A0(0yb=6|0M2VbX1t4:4$7Db/0l0_0l128w0h6Ca+3E0$0h0D0_140k0:0 7$1X4(2^421 1-1/1;a 3z2z2q2s1b2F0.0$5*0tbq0X0+2a1s4/4+a 364.cqaV5D0L7.aA764 aD0M5Och0:cjb7cmb@9H9|aJ6E9ta0c~7K8Q9!9F6w0b0l5Q2:5T2O9_ap8-7s7%6t6E7y6}aO6i0l9d7Ha#dn3M7c7N9vdf8~5!9zd7d95Rdccdded26p7#9l6?aK9 a(8$9TaQdtaEda5SbWcYaMdAc:8HdP2Z9n6;5ca*cga-2!a}1S040V000N1ZbQc48x1f3C9:dX2Pb:0N0b1qbCc8000L0m5Scsb$2cbPcobPbr003%bf0`br0N0r0ibx1p2Mb/0*0 4#c;1+aZe00 2|0TbNb%8z1H0%060Kcx0 c36z0-0yb10t12b$bJ1_2c2Q2feW000:2Pelea1x1_ewctcvbucybgb`1Y1!3zcF211:2u7KcL2B2D0.270:2VaZbf0H241HcZ4T374Rc(6E0$0I1b031A0N0z125Qb*1`0s02030j0f0n2g0h1i5V8:dN0u0G0/0V0V0Q0l0U0QfH0?fI9ddSd56+8)4QfCc 1b0,fMfF0l0.0Q0U0d0!fZ0.fQ5r9Xc=0A0%9Za)fX04f)fO0Q0?0W0laS5k0Qf.ak9-1}0H2j04021F0k9)030=0L0S0C0$0Fgb0:gd0n5y9nfhfjflfn0(fpbrb,b.0:4e9gfEfGfPdT9efS6 9Yf@4udN7=d%al9#fR9Sf_gP6Me91CeTdxdIa2d!aAg8ahgc9)f8a`e,gmgoadgC8fdCdVdFbYg49XfU6.4m5A42gs04fk12cb1C2qbqb+b-b/g@7Cd|0:d~0He0c|dBgWg#d(9b04a4gJ9g7bdDdbeBg?d+0;c(1W4Ta/4)e@cD4ge`cHe}67e cN040p3%0s0k7O37c!3-c$aJff7Kh4fk0Wfmfobfb;ftfvfx0Mfzhld+f_gEfHfJfLfNgGhu9Lf/dT6,fVf^d6fZ0Vf#f%f)f+0Qf-gHgTdQ6E0Rf;f?hf92f{fIf~g09Pg2g}dTg*gag,0ngfghgjglizgqfgfih5guh,b*gzheh^d6h`h gU7KgIiTfT1b0Fh0gNgV9uivi07Cho0lgYe+hpcJ8-c}hq7Kixg;9)0YhThV0Li_gpdZaefWd6hwg`hzigi2i)5vg iGh%iIh62gb$2CehhcgAin9.9:hi1.hkfBdy7 g(ju6vho9HhtiW8Sg_dEj7aAd*fChCd-hEa|hHcCe_1/e{cI9nhP2C1b0obTbVd`bJ2Q9@9:0H6PgB4RhYfd37h$67h(iKgwh-frh/fwfyfAcdjn6iiRh|fM0Vf|i(jC3zi4k06Ji8iaf(f*f,k7ii7Kik5a0%4kj39~ipf}f g10ug3j8g59ni^iziBgigki jdj=jfj@gxjliOkpjDk2ki9,am8)4ci!4Di$d1kRgSj9k8g^i+i-g!hmaDkAgn9)j(14j+0mkFj1kbaEj5jFddkQgRkk8)iZkV1ch24gj?h7jihagyhdj,kN9ghhhjh@jH7Rhni%dZjBkj9~k{hyk}k^hBhDhYhG0g3ma/0`6!0H04.

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