Juego de vida y fatiga

10

El juego de la vida y la fatiga de Stewie es bastante similar al más famoso juego de la vida de Conway .


El universo del Juego de la vida y la fatiga de Stewie (GoLF) es una cuadrícula ortogonal bidimensional infinita de celdas cuadradas, cada una de las cuales se encuentra en uno de los tres estados posibles: vivo, muerto o cansado. Cada celda interactúa con sus ocho vecinos, que son las celdas que están adyacentes horizontal, vertical o diagonalmente. En cada paso en el tiempo, ocurren las siguientes transiciones:

  • Cualquier célula viva con menos de dos vecinos vivos muere, como si fuera causada por la subpoblación.
  • Cualquier célula viva con dos o tres vecinos vivos vive hasta la próxima generación.
  • Cualquier célula viva con más de tres vecinos vivos muere, como por sobrepoblación.
  • Cualquier célula muerta con exactamente tres vecinos vivos se convierte en una célula viva, como por reproducción.
  • Cualquier célula que haya estado viva durante dos generaciones consecutivas muere, como por fatiga. No puede despertar a la vida nuevamente hasta la próxima generación
  • Cualquier celda que esté fuera del límite de la cuadrícula de entrada está muerta, como si se hubiera caído de un acantilado.

Desafío:

Su desafío es tomar una cuadrícula de dimensiones n-por-m que represente el estado inicial de un GoLF y un número entero p , y generar el estado del juego después de p generaciones.

Reglas:

  • Los formatos de entrada y salida son opcionales, pero las cuadrículas de entrada / salida deben tener la misma representación
  • Puede elegir cualquier símbolo imprimible para representar células vivas y muertas (usaré 1para células vivas y 0para células muertas).
  • Puede elegir si tiene 0 o 1 indexado. En los ejemplos, p=1significa el estado después de un paso.
  • El código más corto en cada idioma gana
  • La función incorporada para la automatización celular está permitida

Casos de prueba:

En los ejemplos, solo he incluido la cuadrícula de entrada en la entrada, no p . He proporcionado salidas para varios valores p . Solo generará la cuadrícula que va con una entrada dada 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

Sí, soy consciente de que todas las semillas iniciales no terminarán en todas las células muertas.

Stewie Griffin
fuente
Tal vez debería aclarar que el ítem de transición 5 se aplica "al mismo tiempo" que los ítems 1--4, es decir, se basa en el estado antes de haber aplicado 1--4
Luis Mendo
2
"las células, cada una de las cuales se encuentra en uno de los dos estados posibles, vivo o muerto ", parece una definición deliberadamente perversa dado que la regla de fatiga posterior solo puede expresarse en un autómata finito estándar haciendo que cada célula tenga tres estados (muerto, nuevo vivo, vivo durante dos generaciones consecutivas)
Peter Taylor
1
Tengo una regla de Golly para esto si alguien lo quiere.
CalculatorFeline
66
Jugando a GoD, ¿eh?
Adám

Respuestas:

3

MATL , 34 30 25 bytes

¡5 bytes eliminados gracias a una sugerencia de @CalculatorFeline !

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

Pruébalo en línea!

Las entradas son una matriz y un número. La matriz se usa ;como separador de filas. Las matrices para los tres casos de prueba se ingresan como

[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]

Explicación

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
fuente
1
¿Puedes explicar 3Y6con más detalle? Además, si el elemento central del núcleo era .5, podría verificar CGOL con solo 2<value<4. Podría ayudar.
CalculatorFeline
@CalculatorFeline Esa es una muy buena sugerencia, ¡gracias! Condujo a guardar 5 bytes, usar el doble de la máscara y luego probar eso 5<=value<=7. En cuanto a 3Y6, es solo un literal predefinido. También hay 1Y6, que es el barrio de 4
Luis Mendo
1
Huh Eso realmente funcionó. Ordenado.
CalculatorFeline
3

APL (Dyalog Classic 16.0) , 59 bytes

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

Pruébalo en línea! (emulado en Classic 15.0)


APL (Dyalog Unicode 16.0) , 85 bytes

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

Pruébalo en línea! (emulado en Unicode 15.0)


Solicita cuadrícula y luego p . Imprime la nueva cuadrícula después de p generaciones.

Tenga en cuenta que esto utiliza la nueva primitiva (Stencil) que no está incluida en el juego de caracteres clásico, por lo tanto, una versión más corta y una versión de menos bytes.

Explicación a seguir ...

Adán
fuente
El formato de visualización de APL es agradable :-)
Luis Mendo
@LuisMendo En realidad, no se trata de "APL", sino que el intérprete hace una devolución de llamada a esta función APL cuando quiere emitir. La función luego analiza lo que queremos generar y lo modifica en consecuencia. La explicación de la displayfunción está aquí .
Adám
3

Golly RuleLoader, 295 bytes

@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 cuadrícula de entrada debe pegarse, los límites están en el nombre de la regla (por ejemplo, 5* 3is Y:P5,3), presione la barra espaciadora para avanzar.

CalculadoraFeline
fuente
2

Java 8, 333 bytes

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;}

Explicación:

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
fuente