Jeu de vie et de fatigue

10

Le jeu de la vie et de la fatigue de Stewie est assez similaire au plus célèbre jeu de la vie de Conway .


L'univers du jeu de la vie et de la fatigue de Stewie (GoLF) est une grille orthogonale bidimensionnelle infinie de cellules carrées, dont chacune est dans l'un des trois états possibles, vivant, mort ou fatigué. Chaque cellule interagit avec ses huit voisins, qui sont les cellules adjacentes horizontalement, verticalement ou en diagonale. À chaque étape du temps, les transitions suivantes se produisent:

  • Toute cellule vivante avec moins de deux voisins vivants meurt, comme si elle était causée par la sous-population.
  • Toute cellule vivante avec deux ou trois voisins vivants vit jusqu'à la prochaine génération.
  • Toute cellule vivante avec plus de trois voisins vivants meurt, comme par surpopulation.
  • Toute cellule morte avec exactement trois voisins vivants devient une cellule vivante, comme par reproduction.
  • Toute cellule vivante depuis deux générations consécutives meurt, comme par fatigue. Il ne peut pas reprendre vie avant la prochaine génération
  • Toute cellule qui se trouve en dehors de la limite de la grille d'entrée est morte, comme si elle était tombée d'une falaise.

Défi:

Votre défi est de prendre une grille de dimensions n par m représentant l'état initial d'un GoLF, et un entier p , et de sortir l'état du jeu après p générations.

Règles:

  • Les formats d'entrée et de sortie sont facultatifs, mais les grilles d'entrée / sortie doivent avoir la même représentation
  • Vous pouvez choisir n'importe quel symbole imprimable pour représenter les cellules vivantes et mortes (je les utiliserai 1pour les cellules vivantes et 0pour les cellules mortes).
  • Vous pouvez choisir si vous avez 0 ou 1 indexé. Dans les exemples, p=1signifie l'état après une étape.
  • Le code le plus court dans chaque langue gagne
  • La fonction intégrée pour l'automatisation cellulaire est autorisée

Cas de test:

Dans les exemples, j'ai seulement inclus la grille d'entrée dans l'entrée, pas p . J'ai fourni des sorties pour diverses valeurs de p . Vous ne devez sortir que la grille qui va avec une entrée donnée p .

Input:
0   0   0   0   0
0   0   1   0   0
0   0   1   0   0
0   0   1   0   0
0   0   0   0   0

--- Output ---
p = 1
0   0   0   0   0
0   0   0   0   0
0   1   1   1   0
0   0   0   0   0
0   0   0   0   0

p = 2
0   0   0   0   0
0   0   1   0   0
0   0   0   0   0
0   0   1   0   0
0   0   0   0   0

p = 3 -> All dead
---

Input:
0   1   0   0   0   0
0   0   1   0   0   0
1   1   1   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0

--- Output ---
p = 1
0   0   0   0   0   0
1   0   1   0   0   0
0   1   1   0   0   0
0   1   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0

p = 2
0   0   0   0   0   0
0   0   0   0   0   0
1   0   0   0   0   0
0   1   1   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0

p = 3
0   0   0   0   0   0
0   0   0   0   0   0
0   1   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0
0   0   0   0   0   0

p = 4 -> All dead
Input
0   1   1   0   1   1   0
1   1   0   1   1   1   1
0   1   0   0   0   1   0
0   0   0   1   1   0   1
1   0   0   1   0   1   1
0   0   1   1   0   1   1
1   1   0   0   0   0   1

--- Output ---
p = 1
1   1   1   0   0   0   1
1   0   0   1   0   0   1
1   1   0   0   0   0   0
0   0   1   1   0   0   1
0   0   0   0   0   0   0
1   0   1   1   0   0   0
0   1   1   0   0   1   1

p = 2
1   0   0   0   0   0   0
0   0   0   0   0   0   0
1   0   0   1   0   0   0
0   1   1   0   0   0   0
0   1   0   0   0   0   0
0   0   0   0   0   0   0
0   0   1   1   0   0   0   

p = 3
0   0   0   0   0   0   0
0   0   0   0   0   0   0
0   1   1   0   0   0   0
1   1   0   0   0   0   0
0   1   1   0   0   0   0
0   0   1   0   0   0   0
0   0   0   0   0   0   0

p = 4
0   0   0   0   0   0   0
0   0   0   0   0   0   0
1   1   1   0   0   0   0
1   0   0   0   0   0   0
1   0   1   0   0   0   0
0   1   1   0   0   0   0
0   0   0   0   0   0   0

p = 5
0   0   0   0   0   0   0
0   1   0   0   0   0   0
1   0   0   0   0   0   0
0   0   1   0   0   0   0
1   0   0   0   0   0   0
0   1   0   0   0   0   0
0   0   0   0   0   0   0

p = 6
0   0   0   0   0   0   0
0   0   0   0   0   0   0
0   1   0   0   0   0   0
0   1   0   0   0   0   0
0   1   0   0   0   0   0
0   0   0   0   0   0   0
0   0   0   0   0   0   0

p = 7
0   0   0   0   0   0   0
0   0   0   0   0   0   0
0   0   0   0   0   0   0
1   1   1   0   0   0   0
0   0   0   0   0   0   0
0   0   0   0   0   0   0
0   0   0   0   0   0   0

p = 8
0   0   0   0   0   0   0
0   0   0   0   0   0   0
0   1   0   0   0   0   0
0   0   0   0   0   0   0
0   1   0   0   0   0   0
0   0   0   0   0   0   0
0   0   0   0   0   0   0

p = 9 -> All dead

Oui, je suis conscient que toutes les graines initiales ne finiront pas par la mort de toutes les cellules.

Stewie Griffin
la source
Vous devriez peut-être préciser que l'élément de transition 5 est appliqué "en même temps" que les éléments 1 à 4, c'est-à-dire qu'il est basé sur l'état avant d'avoir appliqué 1 à 4
Luis Mendo
2
" cellules, dont chacune est dans l'un des deux états possibles, vivants ou morts " semble être une définition délibérément perverse étant donné que la règle de fatigue ultérieure ne peut être exprimée que dans un automate fini standard en faisant en sorte que chaque cellule ait trois états (morts, nouvellement vivant, vivant pendant deux générations consécutives)
Peter Taylor
1
J'ai une règle Golly pour cela si quelqu'un le veut.
CalculatorFeline
6
Jouer au GoD, hein?
Adám

Réponses:

3

MATL , 34 30 25 octets

5 octets supprimés grâce à une suggestion de @CalculatorFeline !

0ii:"wy*~wt3Y6QZ+5:7mb*]&

Essayez-le en ligne!

Les entrées sont une matrice et un nombre. La matrice utilise ;comme séparateur de lignes. Les matrices des trois cas de test sont entrées comme

[0 0 0 0 0; 0 0 1 0 0; 0 0 1 0 0; 0 0 1 0 0;0 0 0 0 0]
[0 1 0 0 0 0; 0 0 1 0 0 0; 1 1 1 0 0 0; 0 0 0 0 0 0; 0 0 0 0 0 0; 0 0 0 0 0 0; 0 0 0 0 0 0]
[0 1 1 0 1 1 0; 1 1 0 1 1 1 1; 0 1 0 0 0 1 0; 0 0 0 1 1 0 1; 1 0 0 1 0 1 1; 0 0 1 1 0 1 1; 1 1 0 0 0 0 1]

Explication

0     % Push 0. This represents the generation previous to the input one. Actually
      % This should be an array of zeros, but thanks to broadcasting it is
      % equivalent (and saves bytes)
i     % Input: array with starting generation
i     % Input: number of iterations, p.
      % STACK (bottom to top): 0, array with initial generation, p
:"    % Do the following p times
      %   STACK: previous gen, current gen
  wy  %   Swap, duplicate from below
      %   STACK: current gen, previous gen, current gen
  *~  %   Multiply element-wise, negate. This creates a mask of cells that do not 
      %   die of fatigue (they were 0 in the current or in the previous generation)
      %   STACK: current gen, fatigue mask
  wt  %   Swap, duplicate
      %   STACK: Fatigue mask, current gen, current gen
  3Y6 %   Push predefined literal: 8-neighbourhood: [1 1 1; 1 0 1; 1 1 1]
      %   STACK: Fatigue mask, current gen, current gen, 8-neighbourhood
  Q   %   Add 1 element-wise. This gives [2 2 2; 2 1 2; 2 2 2], which will be
      %   used as convolution kernel. Active cells with 2 neighbours will give 5;
      %   inactive cells with 3 neighbours will give 6; and active cells with 3
      %   neighbours will give 7
      %   STACK: Fatigue mask, current gen, current gen, convolution kernel
  Z+  %   2D convolution, keeping size
      %   STACK: Fatigue mask, current gen, convolution result
  5:7 %   Push array [5 6 7]
  m   %   Ismember, element-wise. Cells that give true will survive, unless fatigued
      %   STACK: Fatigue mask, current gen, cells that can survive
  b   %   Bubble up
      %   STACK: Current gen, cells that can survive, fatigue mask
  *   %   Multiply element-wise. This tells which cells survive considering fatigue.
      %   The result is the new generation
      %   STACK: "Current" gen which now becomes old, "new" gen which now becomes
      %   current
]     % End 
&     % Specify that implicit display will show only top of the stack
Luis Mendo
la source
1
Pouvez-vous expliquer 3Y6plus en détail? De plus, si l'élément central du noyau était .5, vous pouvez vérifier CGOL avec juste 2<value<4. Pourrait aider.
CalculatorFeline
@CalculatorFeline C'est une très bonne suggestion, merci! Cela a permis d'économiser 5 octets, d'utiliser deux fois le masque, puis de tester cela 5<=value<=7. Quant à 3Y6, c'est juste un littéral prédéfini. Il y a aussi 1Y6, qui est le 4-quartier
Luis Mendo
1
Huh. Cela a vraiment fonctionné. Soigné.
CalculatorFeline
3

APL (Dyalog Classic 16.0) , 59 octets

⌊{((3∊⌊{⍵,⍵-c}+/,⍵)∧.1>1|c)×(.1×c)+1c2 2⌷⍵}⎕U233A 3 3⍣⎕⊢⎕

Essayez-le en ligne! (émulé sur Classic 15.0)


APL (Dyalog Unicode 16.0) , 85 octets

⌊{((3∊⌊{⍵,⍵-c}+/,⍵)∧.1>1|c)×(.1×c)+1c2 2⌷⍵}⌺3 3⍣⎕⊢⎕

Essayez-le en ligne! (émulé sur Unicode 15.0)


Demande la grille puis la p . Imprime la nouvelle grille après p générations.

Notez que cela utilise la nouvelle primitive (Stencil) qui n'est pas incluse dans le jeu de caractères Classic, donc une version plus courte et une version à moins d'octets.

Explication à suivre…

Adam
la source
Le format d'affichage d'APL est sympa :-)
Luis Mendo
@LuisMendo En fait, ce ne sont pas des "APL" mais plutôt l'interpréteur fait un rappel de cette fonction APL quand il veut sortir. La fonction analyse ensuite ce que nous voulons sortir et le modifie en conséquence. L'explication de la displayfonction est ici .
Adám
3

Golly RuleLoader, 295 octets

@RULE Y
@TABLE
n_states:3
neighborhood:Moore
symmetries:permute
var z={1,2}
var y=z
var x=z
var w=z
var u=z
var a={0,z}
var b=a
var c=a
var d=a 
var e=a
var f=a
var g=a 
var h=a
0,z,y,x,0,0,0,0,0,1
z,a,0,0,0,0,0,0,0,0
z,y,x,w,u,a,b,c,d,0
2,a,b,c,d,e,f,g,h,0
1,a,b,c,d,e,f,g,h,2
@COLORS
2 255 0 0

La grille d'entrée doit être collée, les limites sont dans le nom de la règle (par exemple 5* 3est Y:P5,3), appuyez sur espace pour avancer.

CalculatorFeline
la source
2

Java 8, 333 octets

int[][]G(int p,int[][]s){for(int h=s.length,w=s[0].length,y,x,n,a,b,t[][]=new int[h][w],i=0;i++<2*p;)for(y=0;y<h;++y)for(x=0;x<w;++x)if(i%2>0){for(n=0,a=y-2;++a<y+2;)for(b=x-2;++b<x+2;)n+=a>=0&a<h&b>=0&b<w&(a!=y|b!=x)&&s[a][b]>0?1:0;t[y][x]=s[y][x]<1?n==3?1:0:n<2|n>3|s[y][x]>1?0:2;}else s[y][x]=i==2*p&t[y][x]>1?1:t[y][x];return s;}

Explication:

int[][]G(int p,int[][]s){
    for(int h=s.length,w=s[0].length,y,x,n,a,b,t[][]=new int[h][w],       //height, width, vars, temp array
            i=0;i++<2*p;)                                                 //for 2*generations: 1. calculate in temporary t, 2. copying to s
        for(y=0;y<h;++y)                                                  //for each row
            for(x=0;x<w;++x)                                              //for each column
                if(i%2>0){                                                //1. calculate
                    for(n=0,a=y-2;++a<y+2;)                               //n = number of alive cells around [y][x]. row above, at and below y
                        for(b=y-2;++b<y+2;)                               //column left, at and right of x
                            n+=a>=0&a<h&b>=0&b<w&(a!=y|b!=x)&&s[a][b]>0?1:0;    //if within bounds and not the cell itself, add 1 if alive.
                    t[y][x]=s[y][x]<1?n==3?1:0:n<2|n>3|s[y][x]>1?0:2;     //save next state in temporary, depending on rules. alive cells become 2.
                }
                else                                                      //2. copy temporary t to s
                    s[y][x]=i==2*p&t[y][x]>1?1:t[y][x];                   //if last generation, replace 2 by 1
    return s;
}
Sebastian Matschke
la source