Simula la regla 110


27

La regla 110 es un autómata celular con algunas propiedades interesantes. Su objetivo es simular una regla 110 en la menor cantidad de caracteres posible.

Para aquellos que no saben, la regla 110 se simula línea por línea en una cuadrícula. Cada cuadrado en una línea de la cuadrícula mira los cuadrados de arriba, arriba a la izquierda y arriba a la derecha para determinar qué celda debería ser.

current pattern  111 110 101 100 011 010 001 000
new cell          0   1   1   0   1   1   1   0

Entrada: números del 0 al 39 que representan el enésimo cuadro de entrada de la fila superior, en cualquier formato razonable (cadena separada por comas, lista, argumentos de función). Para acomodar idiomas indexados en 1, los números también pueden estar indexados en 1 y, por lo tanto, varían de 1 a 40.

Entrada de ejemplo:

38,39

Salida: una cuadrícula de 40 x 40 que representa la ejecución de autómatas, incluida la primera fila. Debe dejar 0 en blanco y 1 como cualquier carácter de impresión visible. Se permiten espacios finales, siempre que la cuadrícula real se pueda distinguir razonablemente. La parte inferior de la cuadrícula puede tener una nueva línea, pero no debe haber líneas en blanco entre las líneas de la cuadrícula.

Salida de ejemplo:

                                  XX
                                 XXX
                                XX X
                               XXXXX
                              XX   X
                             XXX  XX
                            XX X XXX
                           XXXXXXX X
                          XX     XXX
                         XXX    XX X
                        XX X   XXXXX
                       XXXXX  XX   X
                      XX   X XXX  XX
                     XXX  XXXX X XXX

etc.

Nota: Ya se ha hecho una pregunta similar sobre los autómatas celulares 1D, pero espero que, al usar solo una regla, se puedan escribir respuestas más cortas.


44
¿Los patrones se envuelven (es decir, la celda del extremo izquierdo verifica la celda del extremo derecho en la línea que está encima)?
Ventero

44
Si es singular, entonces es un autómata celular .
ClickRick

1
Las respuestas pueden ser fraccionalmente más cortas que Simular cualquier autómata celular 1D porque la regla está codificada en lugar de tener que analizarla desde la entrada, pero aparte de eso, las respuestas serán las mismas. Si se tratara de una regla diferente, entonces habría un potencial de ahorro, pero ¿cómo demonios, si se aplicara una regla poderosa de Turing, ahorraría algo más que una implementación general?
Peter Taylor

1
@Ventero No lo hacen en esta versión.
qwr

1
@BMO esta es una pregunta antigua, pero dado que hoy en día el consenso es permitir formatos de entrada flexibles, modificaré la pregunta para permitirlo
qwr

Respuestas:


8

CJam - 47

S40*l',/{i'!t}/{N40,S3$S++f{>3<2b137Yb='!^}}39*

Se utiliza !para las celdas "1".

Pruébalo en http://cjam.aditsu.net/

Explicación:

S40*hace una cadena (matriz) de 40 espacios,
l',/lee una línea y se divide por comas,
{…}/ejecuta el bloque para cada elemento (los números en forma de cadena)
: i'!tconvierte el número en entero y establece el elemento en esa posición en la cadena anterior (inicialmente 40 espacios ) a '!'
En este punto hemos obtenido la primera línea.
{…}39*ejecuta el bloque 39 veces
- Nagrega una nueva línea
- 40,hace la matriz [0 1… 39]
- S3$S++copia la línea anterior (posición 3 en la pila) y la rellena con un espacio en cada lado
- f{…}ejecuta el bloque para {cada número de 0 a 39} y {la línea rellenada}
: >3<toma una porción de 3 elementos de la línea rellenada que comienza en el número actual
- 2bconvierte de base 2; los elementos que dividimos no son dígitos de base 2, pero los caracteres se convierten a sus valores ASCII y '' mod 8 es 0 y '!' mod 8 es 1
- 137Ybconvierte 137 a base 2 ( Y= 2), obteniendo [1 0 0 0 1 0 0 1], que es 110 invertido y negado (en 8 bits)
- ='!^obtiene el correspondiente dígito de base 2 (el La matriz se envuelve para que el índice se tome mod 8) y xor con el '!' carácter, que resulta en '!' para 0 y '' para 1


17

Ruby, 113 caracteres

c=[0]*41
eval"[#{gets}].map{|i|c[i]=1}"+'
c=(0..39).map{|x|putc" X"[u=c[x]]
110[4*c[x-1]+2*u+c[x+1]]}<<0;puts'*40

Toma entrada en stdin. Para usar una regla diferente, simplemente reemplace el 110en la última línea con cualquier regla que desee probar.

Ejemplo:

$ ruby 110.rb <<< 38,39
                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X

8

Mathematica, 122 bytes

f[a_]:=Riffle[CellularAutomaton[110,Array[If[MemberQ[ToExpression["{"<>a<>"}"],#-1],1,0]&,40],39]/.0->" "/.1->"X","
"]<>""

Sí, puede ver esto como un abuso de esta laguna , pero a) esa laguna está bastante disputada, b) una pregunta de Autómata celular necesita una respuesta de Mathematica (especialmente una sobre la Regla 110) yc) la respuesta de Ruby de Ventero es más corta de todos modos, así que no No creo que se haya hecho ningún daño.

La mayoría de los caracteres se utilizan para el análisis de entrada y el formato de salida. El autómata real se simula usando

CellularAutomaton[110,initialGrid,39]

Esto utiliza condiciones de contorno periódicas (por lo que la cuadrícula se ajusta)


8

Python - 141

i=input()
o=range(40)
l=''.join(' X'[c in i]for c in o)
for r in o:print l;l=''.join('X '[l[c-1:c+2]in('XXX','   ','X  ','','  ')]for c in o)

Ejecutar como p. Ej. python 110.py <<< 38,39


3
['X',' ']podría cambiarse 'X 'para guardar 5 caracteres.
Aficiones de Calvin

16
Mi fruta favorita ahora es uno=range()
kitcar2000

7

q, 67 62 58 bytes

Asume que no hay envoltura:

{40{not(2 sv'flip 1 0 -1 xprev\:x)in 0 4 7}\@[40#0b;x;~:]}

Versión antigua

{40{not(flip(prev;::;next)@\:x)in 3 cut 111100000b}\@[40#0b;x;not]}
{40{not(flip 1 0 -1 xprev\:x)in 3 3#111100000b}\@[40#0b;x;~:]}

5

Python, 186

def r(s,m=range(40)):
 s=[int(i in s)for i in m]
 for g in m:print''.join([' X'[i]for i in s]);s=[int(not''.join(map(str,s[i-1:i+2]if i else s[:2]))in'111 100 000 00'.split())for i in m]

Decente pero probablemente no óptimo.

No especificó cómo se obtiene la entrada, así que simplemente hice una función.

Use ejemplo:

r ([38,39])

Salida:

                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X

Especifiqué la entrada: en su caso, tendría que usar input () y formatear la entrada como se especifica en la publicación original.
qwr

5

Mathematica, 113 caracteres

Otra respuesta de Mathematica usando CellularAutomaton.

Print@@" "["X"][[#]]&/@CellularAutomaton[110,SparseArray[#+1->1&/@ImportString[InputString[],"CSV"][[1]],40],39];

Interesante, ¿cómo " "["X"][[#]]&funciona?
Martin Ender

@ m.buettner " "["X"][[1]]es "X". " "["X"][[0]]devuelve la cabeza de " "["X"], a saber " ".
alephalpha

Oh ya veo. Entonces, eso generalmente guarda un personaje para las listas. Eso es realmente inteligente. Supongo que podría agregarlo a codegolf.stackexchange.com/questions/12900/…
Martin Ender

4

C - 178

Este código depende del hecho de que cada fila de una matriz se almacena en la memoria contigua. Además, no imprime la primera fila, pero imprime las siguientes 40, ya que las reglas solo especifican una cuadrícula de 40x40.

Con sangría solo para facilitar la lectura, el recuento de bytes solo incluye el código necesario.

a[41][42],i,j,*t;
main(){
    while(scanf("%d,",&j)>0)
        a[i][j]=1;
    for(;i<40;i++,puts(""))
        for(j=0;++j<40;)
            t=&a[i][j],
            putchar((*(t+42)=1&(110>>(*(t+1)?1:0)+(*t?2:0)+(*(t-1)?4:0)))?88:32);
}

3

Lua - 351

No es el idioma ideal para jugar al golf.

s,n,t,u=arg[1],{},table.remove,table.insert
for i=1,40 do u(n,i,'.') end
for i in s:gmatch("%d+")do u(n,i,'x');t(n)end
function a(b) c="";for i=1,40 do c=c..b[i] end;print(c);return c end
for i=1,40 do z= n[40]..a(n)..n[1];for k=2,41 do y=string.sub(z,k-1,k+1);if y=="xxx"or y=="x.." or y=="..." then u(n,k-1,'.')else u(n,k-1,'x')end;t(n)end end

1
do u(n,i,'x')eso es intencional, ¿no?
Stan Strum

3

Haskell , 175 170 169 136 127 124 bytes

−9 bytes gracias a @bmo

t(a:b:r:_)=mod(b+r+b*r+a*b*r)2
w%a=take 40.map w.iterate a
d l=t%tail$0:l++[0]
f l=map(" #"!!)%d$(fromEnum.(`elem`l))%succ$0

Pruébalo en línea!


3

Haskell , 135 131 130 bytes

-1 byte gracias a Ørjan Johansen (reorganización take 40)

Enfoque completamente diferente a la respuesta de FrownyFrog pero sobre la misma longitud:

(a?b)r=mod(b+r+b*r+a*b*r)2
r x=0:(zipWith3(?)x=<<tail$tail x++[0])
f y=take 40$map(" o"!!)<$>iterate r[sum[1|elem i y]|i<-[0..40]]

1 indexación y tiene un espacio líder en cada línea, ¡ pruébelo en línea!

Explicación

410 01

f y=                               [sum[1|elem i y]|i<-[0..40]]

40

    take 40$              iterate r

0 01

            map(" o"!!)<$>

r110zipWith3(?)

r x=0:(zipWith3(?)x=<<tail$tail x++[0])

El (?)operador es la parte más interesante de la solución: anteriormente utilicé una regla booleana generada con un mapa de Karnaugh, pero resulta que hay una forma aún más concisa:

(a?b)r=mod(b+r+b*r+a*b*r)2

1
Guardar un byte poniendo take 40$antes map(" o"!!)<$>.
Ørjan Johansen

3

Cáscara , 31 28 bytes

¡Ja, Husk está venciendo a Jelly!

†!¨↑¨↑40¡ȯẊȯ!ḋ118ḋėΘ`:0M#ŀ40

Pruébalo en línea!

Explicación y Ungolfed

Antes de agregar una explicación, déjame desglosar esto un poco. Primero, eliminemos las diversas composiciones, agreguemos paréntesis explícitos y descomprimamos la ¨↑¨cadena. También vamos a reemplazar 40con 4una explicación más legible:

†!"t "↑4¡(Ẋ(!ḋ118ḋė)Θ`:0)M#ŀ4  -- example input: [3]
                           ŀ4  -- lower range of 4: [0,1,2,3]
                         M     -- map over left argument
                          #    -- | count in list
                               -- : [0,0,0,1]
        ¡(              )      -- iterate the following indefinitely (example with [0,1,1,1])
                     `:0       -- | append 0: [0,1,1,1,0]
                    Θ          -- | prepend 0: [0,0,1,1,1,0]
          Ẋ(       )           -- | map over adjacent triples (example with  1 1 0
                  ė            -- | | create list: [1,1,0]
                 ḋ             -- | | convert from base-2: 6
                               -- | | convert 118 to base-2: [1,1,1,0,1,1,0]
                               -- | | 1-based index: 1
                               -- | : [1,1,0,1]
                               -- : [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1],[1,1,1,1],[1,0,0,1],...]
      ↑4                       -- take 4: [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1]]
†                              -- deep map the following (example with [1,1,0,1])
 !"t "                         -- | use each element to index into "t ": "tt t"
                               -- : ["   t","  tt"," ttt","tt t"]

2

Java, 321 caracteres

Entrada pasada como argumento desde la línea de comando, por ejemplo java R 38,39

Nunca he escrito más código Java ofuscado :-)

class R{public static void main(String[]a) {
Integer s=40;boolean[]n,o=new boolean[s];
for(String x:a[0].split(","))o[s.valueOf(x)]=s>0;
for(Object b:o){n=o.clone();
for(int j=0;j<s;j++){
boolean l=j>1&&o[j-1],r=o[j],c=j+1<s&&o[j+1];
n[j]=!(l&c&r|l&!c&!r|!(l|c|r));
System.out.print((r?"X":" ")+(j>s-2?"\n":""));
}o=n;}}}

2

Actualización: Ejemplo de salida correcto aquí (con 40 líneas no 50): Nueva salida a continuación (eliminada la anterior por brevedad):

                                      xx
                                     xxx
                                    xx x
                                   xxxxx
                                  xx   x
                                 xxx  xx
                                xx x xxx
                               xxxxxxx x
                              xx     xxx
                             xxx    xx x
                            xx x   xxxxx
                           xxxxx  xx   x
                          xx   x xxx  xx
                         xxx  xxxx x xxx
                        xx x xx  xxxxx x
                       xxxxxxxx xx   xxx
                      xx      xxxx  xx x
                     xxx     xx  x xxxxx
                    xx x    xxx xxxx   x
                   xxxxx   xx xxx  x  xx
                  xx   x  xxxxx x xx xxx
                 xxx  xx xx   xxxxxxxx x
                xx x xxxxxx  xx      xxx
               xxxxxxx    x xxx     xx x
              xx     x   xxxx x    xxxxx
             xxx    xx  xx  xxx   xx   x
            xx x   xxx xxx xx x  xxx  xx
           xxxxx  xx xxx xxxxxx xx x xxx
          xx   x xxxxx xxx    xxxxxxxx x
         xxx  xxxx   xxx x   xx      xxx
        xx x xx  x  xx xxx  xxx     xx x
       xxxxxxxx xx xxxxx x xx x    xxxxx
      xx      xxxxxx   xxxxxxxx   xx   x
     xxx     xx    x  xx      x  xxx  xx
    xx x    xxx   xx xxx     xx xx x xxx
   xxxxx   xx x  xxxxx x    xxxxxxxxxx x
  xx   x  xxxxx xx   xxx   xx        xxx
 xxx  xx xx   xxxx  xx x  xxx       xx x
xx x xxxxxx  xx  x xxxxx xx x      xxxxx
xxxxxx    x xxx xxxx   xxxxxx     xx   x

Al hacer otro rompecabezas, aprendí algo interesante sobre las instrucciones de anidamiento en bucles for en php, y de repente son mucho más complejas de lo que pensé originalmente. Cuando tengo tiempo, creo que puedo superar este puntaje considerablemente. Por ahora, sin embargo, se mantiene sin cambios en un 408 no competitivo.


Mi php versión 408 caracteres:

Este fue un gran rompecabezas. También pasé años jugando con las entradas, ya que estas son cosas fascinantes que hay que decir. De todos modos, aquí está mi versión de PHP (que no es tan buena como algunas de las respuestas publicadas, pero está completa. En la posición 0 solo tome arriba y arriba a la derecha, en la posición 39 solo tome arriba y arriba a la izquierda, es decir, sin envoltura. Entonces aquí es mi versión

<?php $a='38,39';$b='';$d=explode(',',$a);for($i=0;$i<40;++$i){$c=' ';
foreach($d as $k=>$v){if($v == $i){$c='x';}}$b.=$c;}echo $b."\n";
for($x=1;$x<41;++$x){$o='';for($i=1;$i<41;++$i){if(($i>1)AND(substr($b,$i-2,1)=='x')){
$l=1;}else{$l=0;}if((substr($b,$i-1,1))=='x'){$v=1;}else{$v=0;}if((substr($b,$i,1))=='x'){
$r=1;}else{$r=0;}if((($l+$v+$r)==2)OR(($v+$r)==1)){$o.='x';}else{$o.=' ';}}
echo $o."\n";$b=$o;}?>

Puede verlo y ejecutarlo aquí: http://codepad.org/3905T8i8

La entrada es una cadena de entrada al inicio como $ a = '38, 39 ';

La salida es la siguiente:

xx removed as was too long originally - had 50 lines, not 40 xx

¡¡¡Espero que te guste!!!

PD: Tuve que agregar algunos saltos de línea al código para que pudieras verlo todo y que no se extendiera por la página con una barra de desplazamiento.


Su salida tiene 50 líneas
aditsu

Ah, eso fue porque estaba jugando con él después de terminar y ver lo que sucedió. Alterar ligeramente las reglas tiene efectos tan interesantes. De todos modos lo he cambiado a 40 ahora y lamento haberlo perdido.
Paul Drewett

Es posible que también desee cambiar la salida: p
aditsu

Se corrigió la salida y se agregó un nuevo enlace de teclado con el valor correcto. Gracias de nuevo.
Paul Drewett

2

Stax , 24 bytes CP437

╦♥µ╤u{£┬íQ<;▀ΦΣ╢╕╚äZ↕áû↑

¡Ejecute y depure en línea!

Utiliza el punto de código 1 en CP437 para las celdas "1".

Excelente caso para mostrar el poder de este lenguaje.

Explicación

Utiliza la versión desempaquetada (29 bytes) para explicar.

0]40X*,1&xDQ0]|S3B{:b^374:B@m
0]40X*                           Prepare a tape with 40 cells
      ,1&                        Assign 1 to the cells specified by the input
         xD                      Repeat the rest of the program 40 times
           Q                     Output current tape
            0]|S                 Prepend and append a 0 cell to it
                3B               All runs of length 3
                  {         m    Map each run with block
                   :b            Convert from binary
                     ^           Increment (call this value `n`)
                      374:B      The binary representation of 374
                                 [1,0,1,1,1,0,1,1,0]
                                 which is `01101110` reversed and prepended a 1
                           @     Element at 0-based index `n`

1

K (ngn / k) , 44 35 bytes

{"X "39{(2\145)@2/'3'1,x,1}\^x?!40}

Pruébalo en línea!

{ } funcionar con argumento x

!40 lista de entradas de 0 a 39

x?encuentre sus índices en x, use 0N(el "entero nulo") para no encontrado

^¿Cuáles de ellos son nulos? esto nos da la entrada, negada

39{ }\ aplicar 39 veces, recogiendo resultados intermedios en una lista

1,x,1 rodear la lista con 1s (0s negados)

3' triples de artículos consecutivos

2/' decodificación binaria cada

@ utilizar como índices en ...

2\145 codificación binaria 145 (bits negados de 110)

"X "finalmente, use la matriz 40x40 como índices en la cadena "X "( @aquí está implícito)


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.