¡La vida puede ser colorida!

30

Cada célula en un autómata celular realista solo necesita un bit para representarla, ya que solo puede estar viva o muerta. Eso significa que solo hay dos colores; bastante aburrido.

Las imágenes normales tienen 24 bits por píxel (8 en cada uno de RGB). ¡Esto significa que en una imagen normal con píxeles como celdas puede simular 24 juegos realistas a la vez!

Reto

Su tarea es escribir un programa que aplicará una generación de las reglas de un autómata celular realista a una imagen de profundidad de 24 bits (en cualquier formato conocido que desee), y generará la imagen resultante.

Cada una de las 24 capas utilizará el mismo conjunto de reglas realista, estrictamente dentro de su propia capa. Las 24 capas no interactúan entre sí.

también

  • Los ceros son células muertas y los unos son células vivas.
  • Las condiciones de contorno son periódicas (formando un toro).
  • Cualquier dimensión de imagen debería funcionar.

De entrada y salida

Su programa necesita tomar 3 argumentos, a través de stdin o línea de comando (o el equivalente más cercano de su idioma):

  1. El nombre del archivo de imagen de entrada.
  2. Una cadena de los dígitos 0 a 8 en orden creciente que denota cuando nacen nuevas celdas:
    • Si el dígito d está en la cuerda y luego las células muertas cobran vida cuando tienen d vecinos de vida.
    • Ejemplo: vida3 normal : las células muertas con exactamente 3 vecinos vivos cobran vida.
  3. Una cadena de los dígitos del 0 al 8 en orden creciente que indica cuándo sobreviven las celdas existentes:
    • Si el dígito d está en la cadena, las células vivas con d vecinos vivos sobreviven hasta la próxima generación, de lo contrario mueren.
    • Ejemplo: 23es vida normal: solo las celdas con exactamente 2 o 3 vecinos sobreviven a la siguiente ronda.

Tenga en cuenta que siempre se usa el vecindario de Moore . Lee esto o esto para obtener más información sobre lo que define con precisión un autómata realista y muchos conjuntos de reglas interesantes.

La imagen de salida de 1 generación posterior debe mostrarse o guardarse como out.png( bmpo lo que sea).

Sumisión

El código más corto en bytes gana.

Usted está obligado a incluir al menos una imagen de prueba y sus tres generaciones posteriores inmediatas para algunos conjunto de reglas no trivial. Usa tu avatar y las reglas de vida normales si no puedes pensar en algo mejor.

Si lo desea, puede usar esta pistola de planeador Gosper donde los únicos bits vivos están en la capa verde 128 (solo es seguro que funcione en la vida normal):

arma de planeador

Publicar secuencias interesantes o incluso animaciones es muy recomendable.

Pomo de la puerta
fuente
1
Creo que es un duplicado: las únicas partes nuevas se leen desde otro formato de archivo y dividen las capas; ambas son básicas y no representan un desafío por sí mismas.
Howard
1
@Howard Pero, ¿no te interesa ver las imágenes?
3
Sí. PPCG.SE es un lugar de dolor y agonía, no imágenes divertidas y bonitas . Si hace que la idea de bonificación sea un requisito, ¿seguramente la pregunta debe ser lo suficientemente original?
Flonk
3
El claro interés de la comunidad es que los programas no se copien con cambios menores de las respuestas a otras preguntas. Este sitio no funciona sobre la base de "Creo que puede ser divertido, así que está bien". Eso es 4chan.
Peter Taylor
44
@Howard No creo que esto cuente como un duplicado nunca más. Seguramente si codegolf.stackexchange.com/questions/34505/simulate-rule-110 y codegolf.stackexchange.com/questions/4370/… pueden coexistir, entonces esto no es un duplicado en absoluto.
Hobbies de Calvin

Respuestas:

16

MATLAB: 275

Mi favorito de los parámetros que probé es 45678, 568que luego de una desintegración gradual resulta en un cielo de estrellas centelleantes. Esta imagen representa "la desintegración de la persistencia de la memoria".

Código de producción de gif sin golf (acepta PNG sin extensión):

B = input('B', 's') - 48;
S = input('S', 's') - 48;
f0 = input('file: ', 's');
frames = 60;

f = sprintf('%s.png',f0);
fout = sprintf('%s.gif',f0);
first = 1;
img = imread(f);
for i = 1:60
    out = img * 0;
    [r, c, turd] = size(img);
    for b=0:7
        bimg = ~~bitand(img,2^b);
        pimg = [bimg,bimg,bimg;bimg,bimg,bimg;bimg,bimg,bimg];
        fun = @(ro,co) pimg(r+ro:r+r+ro-1,c+co:c+c+co-1,:);
        sum = fun(0,0)+fun(0,1)+fun(0,2)+fun(1,0)+fun(1,2)+fun(2,0)+fun(2,1)+fun(2,2);
        bnew = uint8(bimg & ismember(sum,S) | ~bimg & ismember(sum, B));
        out = out + 2^b * bnew;
    end
    %imwrite(out,'out.png');
       if first
           [img1,img2] = rgb2ind(img,256);
           imwrite(img1,img2,fout,'gif','Loop',Inf);
          imwrite(img1,img2,fout,'gif','WriteMode','append');
           first = 0;
       end
       img = out;
       [img1,img2] = rgb2ind(img,256);
       imwrite(img1,img2,fout,'gif','WriteMode','append');%,'DelayTime', 2*delay);
end

Código de golf que acepta un nombre de archivo completo (que puede ser GIF, JPEG y quizás otras cosas) y escribe en out.png:

I=@()input('','s');B=I();S=I();i=imread(I());o=0;[r,c,t]=size(i);for b=0:7
g=~~bitand(i,2^b);p=repmat(g,3);F=@(z,Z)p(r+z:r+r+z-1,c+Z:c+c+Z-1,:);M=@(A)ismember(F(0,0)+F(0,1)+F(0,2)+F(1,0)+F(1,2)+F(2,0)+F(2,1)+F(2,2),A-48);o=o+2^b*uint8(g&M(S)|~g&M(B));end
imwrite(o,'out.png')

Un hecho previamente descubierto es que los parámetros 12, 1se pueden usar para generar una alfombra-como fractal de Sierpinski. Aquí hay uno con un punto de inicio aleatorio en cada bit:

Feersum
fuente
14

Mathematica, 359

i=InputString;f=Transpose;b=(p=FromDigits/@Characters@#&)@i[];s=p@i[];Map[FromDigits[#,2]&/@#~ArrayReshape~{3,8}&,f[(g=#;{#,Total[g~RotateRight~#&/@Drop[Join@@Table[{i,j},{i,-1,1},{j,-1,1}],{5}],1]}~f~{3,1,2}/.{l_,n_}:>Boole[l<1&&!b~FreeQ~n||l>0&&!s~FreeQ~n])&/@Apply[Join,IntegerDigits[ImageData[Import@i[],y="byte"],2,8],{2}]~f~{2,3,1},{3,1,2}],{2}]~Image~y

Estoy tomando datos de las instrucciones de cadena en el orden (1) reglas de nacimiento, (2) reglas de supervivencia, (3) nombre de archivo, y estoy mostrando el resultado directamente en Mathematica.

Esto debería ser capaz de manejar los formatos más populares, siempre que el archivo tenga una profundidad de 24 bits.

Aquí hay una versión un tanto descuidada:

i = InputString;
f = Transpose;
b = (p = FromDigits /@ Characters@# &)@i[];
s = p@i[];
Map[
  FromDigits[#,2] & /@ #~ArrayReshape~{3, 8} &,
  f[
   (
      g = #;
      {#, 
         Total[g~RotateRight~# & /@ 
           Drop[Join @@ Table[{i, j}, {i, -1, 1}, {j, -1, 1}], {5}], 
          1]}~f~{3, 1, 2} /. {l_, n_} :> 
        Boole[l < 1 && ! b~FreeQ~n || l > 0 && ! s~FreeQ~n]
      ) & /@ 
    Apply[Join, 
      IntegerDigits[ImageData[Import@i[], y = "byte"], 2, 8], {2}]~
     f~{2, 3, 1},
   {3, 1, 2}
   ],
  {2}
  ]~Image~y

Aquí hay dos ejemplos que usan el avatar de Rainbolt :

Perno de lluvia

20 generaciones usando el juego estándar de la vida [3,23]:

ingrese la descripción de la imagen aquí

20 generaciones usando [456,34567]:

ingrese la descripción de la imagen aquí

Y aquí hay un GIF de las primeras 200 generaciones de la última regla. El GIF omite cada tercer cuadro, porque de lo contrario no podría comprimirlo por debajo de 2 MB:

ingrese la descripción de la imagen aquí

Martin Ender
fuente
2
Qué regla más interesante
orgulloso Haskeller
10

Pitón 2, 427

Para aquellos que no tienen Mathematica;)

import Image as I
t=raw_input
r=range
A=I.open(t())
G=map(int,t())
S=map(int,t())
w,h=A.size
B=I.new('RGB',(w,h))
A=[[map(int,("{:08b}"*3).format(*A.load()[x,y]))for y in r(h)]for x in r(w)]
for x in r(w):
 for y in r(h):
  p=''
  for i in r(24):
    c=A[x][y][i]
    n=sum(A[(x+k-1)%w][(y+j-1)%h][i]for j in r(3)for k in r(3))-c
    p+=str(~~[n in G,n in S][c])
  B.load()[x,y]=tuple(int(p[i*8:i*8+8],2)for i in r(3))
B.save('out.bmp')

Solicita el nombre de archivo, luego los casos de nacimiento y luego los casos de supervivencia. Entonces, para las reglas de la vida normal, puede ingresar test.bmp, entonces 3, luego 23(sin comillas ni nada necesario).

Usé el formato de cadena para indexar y recombinar los bits de color, aunque me temo que probablemente no sea óptimo.

Tenga en cuenta que es bastante lento.

Ejemplo

Alta vida y gran mezcla de arte, ¿verdad? (Regla 36/ 23.)

Mona Lisa Original generación 1 Original / Generación 1

generación 2 generación 3 Generación 2 / Generación 3

Pasatiempos de Calvin
fuente
6

Java, 1085 bytes

import java.awt.image.*;import java.io.*;import javax.imageio.*;class F{static int n(boolean[][][]a,int x,int y,int z){int k=0;for(X=Math.max(x-1,0);X<Math.min(x+2,w);X++)for(Y=Math.max(y-1,0);Y<Math.min(y+2,h);Y++)if(a[X][Y][z])k++;return k-(a[x][y][z]?1:0);}static int p(String k){return Integer.parseInt(k,2);}static int w,h,x,y,z,X,Y;public static void main(String[]a)throws Exception{BufferedImage i=ImageIO.read(new File(a[0]));w=i.getWidth();h=i.getHeight();boolean[][][]G=new boolean[w][h][24];for(x=0;x<w;x++)for(y=0;y<h;y++){String k="".format("%24s",Integer.toBinaryString(0xFFFFFF&i.getRGB(x,y)));for(z=0;z<24;z++){G[x][y][z]=k.charAt(z)>48;}}for(x=0;x<w;x++)for(y=0;y<h;y++){String r="",g="",b="",k;for(z=0;z<8;){k=""+n(G,x,y,z);r+=(-1!=(G[x][y][z++]?a[1].indexOf(k):a[2].indexOf(k)))?1:0;}for(;z<16;){k=""+n(G,x,y,z);g+=(-1!=(G[x][y][z++]?a[1].indexOf(k):a[2].indexOf(k)))?1:0;}for(;z<24;){k=""+n(G,x,y,z);b+=(-1!=(G[x][y][z++]?a[1].indexOf(k):a[2].indexOf(k)))?1:0;}i.setRGB(x,y,new java.awt.Color(p(r),p(g),p(b)).getRGB());}ImageIO.write(i,"png",new File("out.png"));}}

Ejemplos (regla 368/245):

Gen 0:

ingrese la descripción de la imagen aquí

Gen 1:

ingrese la descripción de la imagen aquí

Gen 2:

ingrese la descripción de la imagen aquí

Gen 3:

ingrese la descripción de la imagen aquí

Gen 4:

ingrese la descripción de la imagen aquí

SuperJedi224
fuente