Simule cualquier autómata celular 1D


14

El reto

Debe escribir un programa completo que tome siete números de STDIN e imprima el historial bidimensional del autómata celular (CA) en STDOUT. Este es el código de golf.

Formato de entrada La entrada será de siete enteros / cadenas separadas por comas. El primer número es el número de la regla según el código de Wolfram (el nombre estándar para cada regla). El segundo es la configuración inicial inicial. El tercero y cuarto describen qué patrón y cuántas veces debe agregarse a la izquierda de la configuración inicial. como relleno. El quinto y el sexto hacen lo mismo para el lado derecho. El último número es el número de generaciones para ejecutar la simulación.

Entonces, un ejemplo de entrada es 90,11,0,4,0,4,5. Esto debería decirle a su programa que está ejecutando la regla 90 . También debe decirle al programa que desea que la configuración inicial esté 11con la cadena 0agregada 4 veces a ambos extremos, por lo que el patrón de inicio real es 0000110000. También le dice a su programa que ejecute esta simulación durante 5 generaciones.

Salida Su programa debe imprimir toda la matriz de celdas de cada generación (separadas por nuevas líneas), de modo que la salida sea el diagrama de espacio-tiempo de la CA. Para cada generación, el estado de cada celda está determinado por su estado y los estados de las celdas a la izquierda y derecha inmediatas, de acuerdo con la regla proporcionada como entrada. La simulación debe envolver los bordes. Lo primero que se debe imprimir debe ser la matriz inicial como gen. 0.

La entrada 90,11,0,4,0,4,5debería dar como resultado la siguiente salida tan exactamente como sea posible.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

Tenga en cuenta que el estado inicial no está incluido en las cinco generaciones. Observe también que la simulación se envuelve alrededor de los bordes.

Más ejemplos

entrada:

184,1100,01,2,01,1,4

salida:

0101110001
1011101000
0111010100
0110101010
0101010101

entrada:

0,1011,1,0,0,1,2

salida:

10110
00000
00000

Más información sobre cómo funcionan los CA 1D y cómo están numerados


Bien hecho por incluir la regla 0 como un caso de prueba.
Peter Taylor

Me fascina que la regla 90 sea una Junta Sierpinski. Especialmente porque eso fue parte de las pruebas que hice para otro proyecto de Codegolf .
JoeFish

@JoeFish Fue tu imagen la que me llevó a probar esta. Quería hacer una respuesta 8086: matar 2 pájaros, pero probablemente necesitaría operaciones de cadena, por lo que mi emulador no podría ejecutarlo (todavía).
luser droog

Respuestas:


5

Golfscript, 77 73 70 caracteres

','/)~\(~:?;~~*@@~*@+\+{1&}/]({[.,{.[3<?256+]{2base}/\~=\(+}*])n@)\+}*

Gracias a @Howard, quien señaló cómo guardar 4 caracteres.


Puede guardar uno obvio 48--> 1&y creo que también tres más. Puede omitir )antes del bloque (no aumentar el contador) y, por lo tanto, también guardar los dos últimos pops.
Howard

@Howard, gracias. Esos pops al final fueron útiles en una iteración anterior, pero tienes razón en que eliminarlos tiene sentido ahora.
Peter Taylor

5

APL (153 caracteres)

∇ cellularautomaton
  i               ← ⍞
  s               ← (i=',') / ⍳ ⍴i
  (b a x c)       ← {i[s[⍵]↓⍳s[⍵+1]-1]} ¨ ⍳4
  (z x x l x r n) ← ⍎i
  y               ← ⍎ ¨ ⊃ ,/ (l / ⊂a) , b , r / ⊂c
  (n+1) (⊃⍴,y) ⍴ '01'[1+⊃ ,/ y,{({(z ⊤⍨ 8/2)[8 - 2⊥¨ 3 ,/ (⊃⌽⍵),⍵,⊃⍵]}⍣⍵)y} ¨ ⍳n]
∇

Y en forma menos legible, un poco más corta:

i←⍞⋄s←(i=',')/⍳⍴i⋄b a x c←{i[s[⍵]↓⍳s[⍵+1]-1]}¨⍳4⋄z x x l x r n←⍎i⋄y←⍎¨⊃,/(l/⊂a),b,r/⊂c⋄'01'[1+⊃,/y,{({(z⊤⍨8/2)[8-2⊥¨3,/(⊃⌽⍵),⍵,⊃⍵]}⍣⍵)y}¨⍳n]⍴⍨(1+n),⊃⍴,y

Ejemplo:

      cellularautomaton
26,00110,01,4,10,6,7
0101010100110101010101010
1000000011100000000000001
0100000110010000000000011
0010001101101000000000110
0101011001000100000001101
0000010110101010000011000
0000100100000001000110100
0001011010000010101100010

Estoy seguro de que hay margen de mejora (¡incluso encontré algunos cambios al escribir esta publicación!), Pero algunos de ellos podrían implicar cambios fundamentales, y no puedo soportar mirar APL por más tiempo. La variante de APL utilizada aquí es Dyalog APL .


4

Ruby, 165 159 caracteres

a=gets.split ?,
b=a.map &:to_i
c=(x=a[2]*b[3]+a[1]+a[4]*b[5]).chars.map &:hex
(0..b[6]).map{puts c*''
c=(1..w=x.size).map{|i|b[0]>>c[i-1]*2+c[i%w]+c[i-2]*4&1}}

Editar: encontré algunos lugares para pequeñas mejoras.

Ejemplo de ejecución:

> 30,1,0,20,0,20,20
00000000000000000000100000000000000000000
00000000000000000001110000000000000000000
00000000000000000011001000000000000000000
00000000000000000110111100000000000000000
00000000000000001100100010000000000000000
00000000000000011011110111000000000000000
00000000000000110010000100100000000000000
00000000000001101111001111110000000000000
00000000000011001000111000001000000000000
00000000000110111101100100011100000000000
00000000001100100001011110110010000000000
00000000011011110011010000101111000000000
00000000110010001110011001101000100000000
00000001101111011001110111001101110000000
00000011001000010111000100111001001000000
00000110111100110100101111100111111100000
00001100100011100111101000011100000010000
00011011110110011100001100110010000111000
00110010000101110010011011101111001100100
01101111001101001111110010001000111011110
11001000111001111000001111011101100010001

3

C, 303305301 294 292

305 Editar: ¡Uy! Olvidé esocalloc() lleva dos args. Estaba explotando en una entrada más grande.

301 Edición: ¡Ah, ja! Usé micalloc() boo-boo para guardar 2 bytes más al aumentar el tamaño del bloque de la memoria solicitada.

294 Edición: ¡Rompió 300! Eliminó uno de los strcat()sy ajustó algunos bucles. Tengo que usar munch máximo, que es tan divertido decirlo como usarlo.

292 Editar: no necesitaba la +2asignación en memoria.

Yo solía respuesta luser de droog como la idea de base, pero ha cambiado el algoritmo de embalaje, así como una gran cantidad de ajustes y la factorización de las constantes.

r,A,C,n,j;main(){char*s,*p,*t,a[9],b[9],c[9];scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);for(s=calloc(A+++C,9);A--;)strcat(s,A?a:b);for(;C--;)strcat(s,c);p=strdup(s);for(C=strlen(s);A++<n;puts(s),t=p,p=s,s=t)for(j=C;j--;)p[j]=(1<<(s[j?j-1:C-1]*4+s[j]*2+s[(j+1)%C])-336)&r?49:48;}

r,A,C,n,j;
main(){
    char*s,*p,*t,a[9],b[9],c[9];
    scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);
    for(s=calloc(A+++C,9);A--;)
        strcat(s,A?a:b);
    for(;C--;)
        strcat(s,c);
    p=strdup(s);
    for(C=strlen(s);A++<n;puts(s),t=p,p=s,s=t)
        for(j=C;j--;)
            p[j]=(1<<(s[j?j-1:C-1]*4+s[j]*2+s[(j+1)%C])-336)&r?49:48;
}

captura de pantalla1

screenshot2


1
¡Olvidaste hacer que comience C,A,! :)
luser droog

para un montón de memoria, ¿qué pasa brk()? entonces en p=s+C+1;alguna parte.
luser droog

1
¡+1 nuevamente por usar +++!
luser droog

¡Jaja! ¡Cambia todo %[01]a %s! -9 (... muchos años después)
luser droog

1
@luserdroog esto no funciona porque% s es codicioso y también come las comas y otros dígitos.
JoeFish

2

C (487 484 418 con espacios eliminados)

* Cayó 66 con la ayuda de JoeFish *

C,A,r,n,j;main(){char*s,*p,*t,a[9],b[9],c[9];
    scanf("%d,%[01],%[01],%d,%[01],%d,%d",&r,b,a,&A,c,&C,&n);
    s=malloc(strlen(a)*A+strlen(b)+strlen(c)*C+3);*s=0;
    strcat(s,"0");
    for(;A--;)strcat(s,a);
    strcat(s,b);
    for(;C--;)strcat(s,c);
    strcat(s,"0");
    p=malloc((C=strlen(s)-1)+2);
    for(;n--;){
    *s=s[C-1];
    s[C]=0;
    puts(s+1);
    s[C]=s[1];
    for(j=1;s[j+1];j++)
        p[j]=(1<<(s[j-1]-48)*4+(s[j]-48)*2+s[j+1]-48)&r?49:48;
    t=p;p=s;s=t;
    }
    s[C]=0;
    puts(s+1);
}

mecanografiado

josh @ Z1 ~
$! m
hacer ca
cc ca.c -o ca
ca.c: 1: 1: advertencia: la definición de datos no tiene tipo ni clase de almacenamiento
ca.c: En la función 'main':
ca.c: 2: 5: advertencia: declaración implícita incompatible de la función incorporada 'scanf'
ca.c: 3: 7: advertencia: declaración implícita incompatible de la función incorporada 'malloc'
ca.c: 3: 14: advertencia: declaración implícita incompatible de la función incorporada 'strlen'
ca.c: 4: 5: advertencia: declaración implícita incompatible de la función incorporada 'strcat'

josh @ Z1 ~
$ echo 90,11,0,4,0,4,5 | California
-bash: ca: comando no encontrado

josh @ Z1 ~
$ echo 90,11,0,4,0,4,5 | ./California
0000110000
0001111000
0011001100
0111111110
1100000011
0110000110


Agradable. Puede reducir bastantes bytes haciendo que sus intvariables sean globales y eliminando #include: r,A,B,C,n,i,j; main(){char *s...
JoeFish

Ahorre un montón en sus forbucles:for(;A--;)strcat(s,a);
JoeFish

Y reutilizar Ay Cmás tarde para que no tenga que declarar io Bpara nada p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Lo siento, me detendré ahora :)
JoeFish

Ok, mentí, uno más. Deshacerse de 2 despedidas mediante la eliminación --C;: p=malloc((C=strlen(s)-1)+2);. ¡Creo que el código de golf es más divertido que crearlo en primer lugar!
JoeFish

No estaba seguro de eliminar el #includeya que scanfes variadic. Pero probablemente esté bien, ya que solo se llama una vez. ... Mi vieja máquina murió ayer, y todavía estoy instalando Cygwin. Incorporaré esos cambios tan pronto como pueda probarlo. ¡Gracias!
luser droog
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.