Simular Regra 110

27

A regra 110 é um autômato celular com algumas propriedades interessantes. Seu objetivo é simular uma regra 110 no menor número de caracteres possível.

Para quem não sabe, a regra 110 é simulada linha por linha em uma grade. Cada quadrado em uma linha da grade olha para os quadrados acima, acima da esquerda e acima da direita para determinar qual célula deve ser.

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

Entrada: números de 0 a 39 representando a linha superior do enésimo quadrado de entrada, em qualquer formato razoável (sequência separada por vírgula, lista, argumentos de função). Para acomodar idiomas indexados em 1, os números também podem ser indexados em 1 e variam de 1 a 40.

Exemplo de entrada:

38,39

Saída: Uma grade de 40 x 40 representando os autômatos em execução, incluindo a primeira linha. Você deve deixar 0 em branco e 1 como qualquer caractere de impressão visível. Os espaços à direita são permitidos, desde que a grade real possa ser razoavelmente distinguida. A parte inferior da grade pode ter uma nova linha, mas não deve haver linhas em branco entre as linhas da grade.

Exemplo de saída:

                                  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: Uma pergunta semelhante sobre autômatos celulares 1D já foi feita, mas espero que, usando apenas uma regra, respostas mais curtas possam ser escritas.

qwr
fonte
4
Os padrões são agrupados (ou seja, a célula mais à esquerda verifica a célula mais à direita na linha acima dela)?
Ventero
4
Se for singular, é um autômato celular .
ClickRick
1
As respostas podem ser fracionadas mais curtas do que Simular qualquer autômato celular 1D porque a regra é codificada em vez de precisar ser analisada a partir da entrada, mas fora isso, as respostas serão as mesmas. Se fosse uma regra diferente, haveria um potencial de economia, mas como na Terra uma regra especial poderosa de Turing pouparia alguma coisa em uma implementação geral?
Peter Taylor
1
@ Ventero Eles não nesta versão.
Qd #
1
@BMO esta é uma questão de idade, mas já que hoje o consenso é permitir que formatos de entrada flexíveis, vou modificar a pergunta para permitir que ele
QWR

Respostas:

8

CJam - 47

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

Ele usa !para células "1".

Experimente em http://cjam.aditsu.net/

Explicação:

S40*faz uma string (matriz) de 40 espaços
l',/lê uma linha e divide por vírgula
{…}/executa o bloco para cada item (os números em forma de string)
- i'!tconverte o número em número inteiro e define o item nessa posição na string anterior (inicialmente 40 espaços ) para '!'
Neste ponto, obtivemos a primeira linha.
{…}39*executa os blocos 39 vezes
- Nacrescenta uma nova linha
- 40,faz com que a matriz [0 1 ... 39]
- S3$S++cópias da linha anterior (posição 3 na pilha) e almofadas de TI com um espaço de cada lado
- f{…}executa o bloco para a {cada número de 0 para 39} e {linha preenchida}
- >3<pega uma fatia de 3 itens da linha preenchida, começando no número atual
- 2bconverte da base 2; os itens que cortamos não têm dígitos de base 2, mas os caracteres são convertidos em seus valores ASCII e '' mod 8 é 0 e '!' o mod 8 é 1
- 137Ybconverte 137 na base 2 ( Y= 2), obtendo [1 0 0 0 1 0 0 1], que é 110 invertido e negado (em 8 bits)
- ='!^obtém o dígito base-2 correspondente (o array envolve para que o índice seja modificado 8) e xor com o '!' caractere, resultando em '!' para 0 e '' para 1

aditsu
fonte
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

Recebe entrada em stdin. Para usar uma regra diferente, substitua simplesmente 110a última linha pela regra que você deseja tentar.

Exemplo:

$ 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
Ventero
fonte
8

Mathematica, 122 bytes

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

Sim, você pode ver isso abusando dessa brecha , mas a) essa brecha é bastante contestada, b) uma pergunta do Autômato Celular precisa de uma resposta do Mathematica (especialmente uma sobre a Regra 110) ec) a resposta Ruby de Ventero é mais curta, então eu não acho que algum mal está feito.

A maioria dos caracteres é usada para análise de entrada e formatação de saída. O autômato real é simulado usando

CellularAutomaton[110,initialGrid,39]

Isso usa condições de contorno periódicas (para que a grade se envolva).

Martin Ender
fonte
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)

Executar como por exemplo python 110.py <<< 38,39

Alex L
fonte
3
['X',' ']pode ser alterado 'X 'para salvar 5 caracteres.
Calvin's Hobbies
16
Minha fruta favorita agora é umo=range()
kitcar2000
7

q, 67 62 58 bytes

Assume que não há envolvimento:

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

Versão antiga

{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;~:]}
skeevey
fonte
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, mas provavelmente não ideal.

Você não especificou como a entrada é obtida, então eu apenas fiz uma função.

Use exemplo:

r ([38,39])

Saída:

                                      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
Passatempos de Calvin
fonte
Especifiquei input: no seu caso, você teria que usar input () e formatar a entrada conforme especificado na postagem original.
QWR
5

Mathematica, 113 caracteres

Outra resposta do Mathematica usando CellularAutomaton.

Print@@" "["X"][[#]]&/@CellularAutomaton[110,SparseArray[#+1->1&/@ImportString[InputString[],"CSV"][[1]],40],39];
alefalpha
fonte
Interessante, como " "["X"][[#]]&funciona?
Martin Ender
@ m.buettner " "["X"][[1]]é "X". " "["X"][[0]]retorna a cabeça de " "["X"], a saber " ".
Alephalpha
Ah eu vejo. Então, isso geralmente salva um personagem para listas. Isso é realmente inteligente. Acho que você poderia adicioná-lo à codegolf.stackexchange.com/questions/12900/...
Martin Ender
4

C - 178

Esse código depende do fato de que cada linha de uma matriz é armazenada na memória contígua. Além disso, ele não imprime a primeira linha, mas imprime as próximas 40, pois as regras especificam apenas uma grade de 40x40.

Recuado apenas para legibilidade, a contagem de bytes inclui apenas o código necessário.

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);
}
Allbeert
fonte
3

Lua - 351

Não é o idioma ideal para jogar golfe.

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
AndoDaan
fonte
1
do u(n,i,'x')isso é intencional, não é?
181 Stan Strum #
3

Haskell , 175 170 169 136 136 127 124 bytes

−9 bytes graças 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

Experimente online!

FrownyFrog
fonte
3

Haskell , 135 131 130 bytes

-1 byte graças a Ørjan Johansen (reorganização take 40)

Abordagem completamente diferente da resposta do FrownyFrog, mas aproximadamente do mesmo tamanho:

(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

Explicação

4101

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

40

    take 40$              iterate r

01

            map(" o"!!)<$>

r110zipWith3(?)

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

O (?)operador é a parte mais interessante da solução: Anteriormente , usei uma regra booleana gerada com um mapa de Karnaugh, mas acontece que existe uma maneira ainda mais concisa:

(a?b)r=mod(b+r+b*r+a*b*r)2
ბიმო
fonte
1
Salve um byte colocando take 40$antes map(" o"!!)<$>.
Ørjan Johansen
3

Casca , 31 28 bytes

Hah, Husk está batendo Jelly!

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

Experimente online!

Explicação e Não Goleado

Antes de adicionar uma explicação, deixe-me refazer um pouco isso. Vamos primeiro remover as várias composições, adicionar parênteses explícitos e descompactar a ¨↑¨string. Também vamos substituir 40com 4uma explicação mais legível:

†!"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"]
ბიმო
fonte
2

Java, 321 caracteres

Entrada passada como argumento na linha de comando, por exemplo java R 38,39

Eu nunca escrevi código java mais 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;}}}
Tomáš Dvořák
fonte
2

Atualização: Exemplo de saída correto aqui (com 40 linhas e não 50): Nova saída abaixo (removida a anterior por questões de brevidade):

                                      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

Fazendo outro quebra-cabeça, aprendi algo interessante sobre como aninhar declarações em loops no php e, de repente, elas são muito mais complexas do que eu pensava. Quando tenho tempo, acho que posso superar essa pontuação consideravelmente. Por enquanto, embora permaneça inalterado em um 408 não competitivo.


Minha versão php 408 caracteres:

Este foi um ótimo quebra-cabeça. Também passei anos brincando com as entradas, pois essas são coisas fascinantes que devem ser ditas. Enfim, aqui está a minha versão do PHP (que nem chega a ser boa como algumas das respostas postadas, mas está completa. Na 0ª posição, pegue apenas acima e acima da direita, na 39ª posição, pegue apenas acima e acima da esquerda, ou seja, sem quebra. é a minha versão:

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

Você pode vê-lo e executá-lo aqui: http://codepad.org/3905T8i8

Input é uma string de entrada no início como $ a = '38, 39 ';

A saída é a seguinte:

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

Espero que você goste!!!

PS: Eu tive que adicionar algumas quebras de linha ao código para que você pudesse ver tudo e não esticar ao longo da página com uma barra de rolagem.

Paul Drewett
fonte
Sua saída tem 50 linhas
aditsu
Ah, isso foi porque eu estava brincando com ele depois que terminei e vi o que aconteceu. Alterar ligeiramente as regras tem efeitos tão interessantes. Enfim, mudei para 40 agora e desculpe por ter perdido isso.
Paul Drewett
Você também pode alterar a saída: p
aditsu
Corrigida a saída e adicionado novo link do codepad com o valor correto. Mais uma vez obrigado.
Paul Drewett
2

Stax , 24 bytes CP437

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

Execute e depure online!

Usa o ponto de código 1 no CP437 para células "1".

Excelente caso para mostrar o poder desse idioma.

Explicação

Usa a versão descompactada (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`
Weijun Zhou
fonte
1

K (ngn / k) , 44 35 bytes

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

Experimente online!

{ } função com argumento x

!40 lista de ints de 0 a 39

x?encontre seus índices x, use0N (o "número inteiro nulo") para não encontrado

^quais deles são nulos? isso nos dá a entrada, negada

39{ }\ aplicar 39 vezes, coletando resultados intermediários em uma lista

1,x,1 rode a lista com 1s (0s negado)

3' triplos de itens consecutivos

2/' decodificação binária cada

@ use como índices em ...

2\145 codificação binária 145 (bits negativos de 110)

"X "finalmente, use a matriz 40x40 como índices na sequência "X "(o @aqui está implícito)

ngn
fonte