Simule qualquer autômato celular 1D

14

O desafio

Você deve escrever um programa completo que use sete números de STDIN e imprima o histórico bidimensional do autômato celular (CA) em STDOUT. Isso é código de golfe.

Formatação da entrada A entrada será sete números inteiros / seqüências de caracteres separados por vírgulas. O primeiro número é o número da regra de acordo com o código Wolfram (o nome padrão para cada regra). O segundo é a configuração inicial inicial. O terceiro e o quarto descrevem qual padrão e quantas vezes ele deve ser anexado à esquerda da configuração inicial. como preenchimento. O quinto e o sexto fazem o mesmo para o lado direito. O último número é o número de gerações para executar a simulação.

Então, um exemplo de entrada é 90,11,0,4,0,4,5. Isso deve informar ao seu programa que você está executando a regra 90 . Também deve dizer ao programa que deseja que a configuração inicial seja 11com a corda 0anexada 4 vezes para ambas as extremidades, de modo que o padrão de partida real é 0000110000. Ele também informa ao seu programa para executar esta simulação por 5 gerações.

Saída Seu programa deve imprimir toda a matriz de células a cada geração (separadas por novas linhas), para que a saída seja o diagrama de espaço-tempo da CA. Para cada geração, o estado de cada célula é determinado pelo seu estado e pelos estados das células imediatamente à esquerda e à direita, de acordo com a regra fornecida como entrada. A simulação deve envolver as bordas. A primeira coisa impressa deve ser a matriz inicial como gen. 0

A entrada 90,11,0,4,0,4,5deve resultar na seguinte saída o mais exatamente possível.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

Observe que o estado inicial não está incluído nas cinco gerações. Observe também que a simulação envolve as bordas.

Mais exemplos

entrada:

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

resultado:

0101110001
1011101000
0111010100
0110101010
0101010101

entrada:

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

resultado:

10110
00000
00000

Mais informações sobre como a 1D CA funciona e como elas são numeradas

PhiNotPi
fonte
Bem feito para incluir a regra 0 como um caso de teste.
Peter Taylor
Estou fascinado que a regra 90 seja uma junta de Sierpinski. Especialmente porque isso fazia parte dos testes que fiz para outro projeto do Codegolf .
31512 JoeFish
@JoeFish Foi sua imagem que me levou a experimentar esta. Eu queria fazer uma resposta do 8086 - matar 2 coelhos - mas provavelmente precisaria de operações de string, para que meu emulador não pudesse executá-lo (ainda).
Luser droog
Alguém já fez isso: pouet.net/prod.php?which=60478
luser droog

Respostas:

5

Golfscript, 77 73 70 caracteres

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

Graças a @Howard, que apontou como salvar 4 caracteres.

Peter Taylor
fonte
Você pode salvar um óbvio 48--> 1&e acho que também mais três. Você pode omitir )antes do bloco (não aumentar o contador) e, portanto, também salvar os dois últimos pops.
Howard
@ Howard, obrigado. Esses pops no final foram úteis em uma iteração anterior, mas você está certo que eliminá-los faz sentido agora.
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]
∇

E de forma menos legível e ligeiramente mais curta:

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

Exemplo:

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

Tenho certeza de que há espaço para melhorias (eu até encontrei algumas mudanças enquanto escrevia este post!), Mas algumas delas podem envolver mudanças fundamentais, e eu não aguento mais encarar a APL. A variante do APL usada aqui é o Dyalog APL .

Dillon Cower
fonte
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}}

Edit: Encontrei alguns lugares para pequenas melhorias.

Exemplo de execução:

> 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
Howard
fonte
3

C, 303 305 301 294 292

305 Edit: oops. Esqueceu que calloc()leva dois argumentos. Estava explodindo em entradas maiores.

301 Editar: Ah HA! Usei o meu calloc()boo-boo para economizar mais 2 bytes, aumentando o tamanho do bloco da memória solicitada.

294 Editar: Quebrou 300! Eliminou um dos se strcat()ajustou alguns loops. É preciso usar a máxima mastigação, o que é tão divertido de se dizer quanto usar.

292 Edit: Não precisava da +2alocação de memória.

Eu usei a resposta do luser droog como a idéia base, mas mudei o algoritmo de empacotamento, bem como muitos ajustes e fatoração de 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;
}

screenshot1

screenshot2

JoeFish
fonte
1
Você esqueceu de começar C,A,! :)
luser droog
para muita memória, e quanto brk()? então em p=s+C+1;algum lugar.
Luser droog
1
+1 novamente para usar +++!
Luser droog
Haha! Mude todo o %[01]para %s! -9 (... muitos anos depois)
luser droog 27/05
1
@luserdroog isso não funciona porque o% s é ganancioso e também consome vírgulas e outros dígitos.
30817 JoeFish
2

C (487 484 418 com espaços removidos)

* Caiu 66 com a ajuda 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);
}

datilografado

josh @ Z1 ~
$! m
fazer ca
cc ca.c -o ca
ca.c: 1: 1: aviso: a definição de dados não possui tipo ou classe de armazenamento
ca.c: na função 'main':
ca.c: 2: 5: aviso: declaração implícita incompatível da função interna 'scanf'
ca.c: 3: 7: aviso: declaração implícita incompatível da função interna 'malloc'
ca.c: 3: 14: aviso: declaração implícita incompatível da função interna 'strlen'
ca.c: 4: 5: aviso: declaração implícita incompatível da função interna 'strcat'

josh @ Z1 ~
$ eco 90,11,0,4,0,4,5 | ca
-bash: ca: comando não encontrado

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

luser droog
fonte
Agradável. Você pode raspar alguns bytes tornando suas intvariáveis ​​globais e removendo o #include: r,A,B,C,n,i,j; main(){char *s...
JoeFish
Salve um monte em seus forloops:for(;A--;)strcat(s,a);
JoeFish
E re-uso Ae Cmais tarde para que você não tem que declarar iou Bem tudo. p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Desculpe, eu vou parar agora :)
JoeFish 13/12/12
Ok, eu menti, mais uma. Livre-se de 2 bytes eliminando--C; : p=malloc((C=strlen(s)-1)+2);. Eu acho que o código do golfe é mais divertido do que sugeri-lo!
31812 JoeFish
Eu não tinha certeza sobre como remover o #includedesde scanfé variadic. Mas provavelmente está tudo bem, pois é chamado apenas uma vez. ... Minha máquina antiga morreu ontem e ainda estou instalando o Cygwin. Incorporarei essas alterações assim que possível. Obrigado!
Luser droog