Simulez n'importe quel automate cellulaire 1D

14

Le défi

Vous devez écrire un programme complet qui prend sept nombres de STDIN et imprime l'historique STDOUT en deux dimensions de l'automate cellulaire (CA). C'est le golf de code.

Formatage de l'entrée L'entrée sera composée de sept entiers / chaînes séparés par des virgules. Le premier nombre est le numéro de la règle selon le code Wolfram (le nom standard de chaque règle). Le second est la configuration de démarrage initiale. Les troisième et quatrième décrivent quel modèle et combien de fois il doit être ajouté à gauche de la configuration de départ. comme rembourrage. Les cinquième et sixième font de même pour le côté droit. Le dernier nombre est le nombre de générations pour exécuter la simulation.

Ainsi, un exemple d'entrée est 90,11,0,4,0,4,5. Cela devrait indiquer à votre programme que vous exécutez la règle 90 . Il doit également indiquer au programme que vous souhaitez que la configuration initiale soit 11avec la chaîne 0ajoutée 4 fois aux deux extrémités, de sorte que le modèle de démarrage réel est 0000110000. Il indique également à votre programme d'exécuter cette simulation pendant 5 générations.

Sortie Votre programme doit imprimer l'intégralité du tableau de cellules à chaque génération (séparées par des retours à la ligne), de sorte que la sortie soit le diagramme espace-temps de l'autorité de certification. Pour chaque génération, l'état de chaque cellule est déterminé par son état et les états des cellules immédiatement à gauche et à droite, conformément à la règle fournie en entrée. La simulation doit s'enrouler autour des bords. La première chose imprimée devrait être le tableau de départ en tant que gen. 0.

L'entrée 90,11,0,4,0,4,5doit donner la sortie suivante aussi exactement que possible.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

Notez que l'état de départ n'est pas inclus dans les cinq générations. Notez également que la simulation s'enroule autour des bords.

Plus d'exemples

contribution:

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

production:

0101110001
1011101000
0111010100
0110101010
0101010101

contribution:

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

production:

10110
00000
00000

Plus d'informations sur le fonctionnement des CA 1D et leur numérotation

PhiNotPi
la source
Bravo pour avoir inclus la règle 0 comme cas de test.
Peter Taylor
Je suis fasciné que la règle 90 soit un joint Sierpinski. D'autant plus que cela faisait partie des tests que j'ai faits pour un autre projet Codegolf .
JoeFish
@JoeFish C'est votre image qui m'a amené à essayer celui-ci. Je voulais faire une réponse 8086 - tuer 2 oiseaux - mais cela nécessiterait probablement des opérations de chaîne, donc mon émulateur ne pourrait pas (encore) l'exécuter.
luser droog
Quelqu'un l'a déjà fait: pouet.net/prod.php?which=60478
luser droog

Réponses:

5

Golfscript, 77 73 70 caractères

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

Merci à @Howard, qui a expliqué comment enregistrer 4 caractères.

Peter Taylor
la source
Vous pouvez en enregistrer une évidente 48--> 1&et je pense aussi trois autres. Vous pouvez omettre )avant le bloc (pas augmenter le compteur) et donc enregistrer également les deux derniers pops.
Howard
@Comment, merci. Ces pops à la fin étaient utiles dans une itération antérieure, mais vous avez raison de dire que les éliminer a du sens maintenant.
Peter Taylor
5

APL (153 caractères)

∇ 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]
∇

Et sous une forme moins lisible et légèrement plus courte:

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

Exemple:

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

Je suis certain qu'il y a place à amélioration (j'ai même trouvé quelques changements en écrivant cet article!), Mais certains pourraient impliquer des changements fondamentaux, et je ne peux plus supporter de regarder APL plus longtemps. La variante d'APL utilisée ici est Dyalog APL .

Dillon Cower
la source
4

Ruby, 165 159 caractères

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: j'ai trouvé quelques endroits pour de petites améliorations.

Exemple d'exécution:

> 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
la source
3

C, 303 305 301 294 292

305 Modifier: oups. Oublié cela calloc()prend deux arguments. Il explosait sur une entrée plus importante.

301 Edit: Ah HA! J'ai utilisé mon calloc()boo-boo pour économiser 2 octets supplémentaires en augmentant la taille du bloc de la mémoire demandée.

294 Edit: Broke 300! Éliminé l'un des strcat()s et modifié quelques boucles. Je dois utiliser le munch maximal, ce qui est aussi amusant à dire qu'à utiliser.

292 Edit: n'a pas eu besoin de l' +2allocation en mémoire.

J'ai utilisé la réponse de luser droog comme idée de base, mais j'ai modifié l'algorithme d'encapsulation, ainsi que de nombreux ajustements et factorisations des 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;
}

capture d'écran1

capture d'écran2

JoeFish
la source
1
Vous avez oublié de le faire démarrer C,A,! :)
luser droog
pour beaucoup de mémoire, qu'en est-il brk()? puis p=s+C+1;quelque part.
luser droog
1
+1 à nouveau pour l'utilisation +++!
luser droog
Haha! Changez tout %[01]en %s! -9 (... de nombreuses années plus tard)
luser droog
1
@luserdroog cela ne fonctionne pas car le% s est gourmand et mange aussi les virgules et autres chiffres.
JoeFish
2

C (487 484 418 avec espaces supprimés)

* A chuté de 66 avec l'aide 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);
}

manuscrit

josh @ Z1 ~
$! m
faire ca
cc ca.c -o ca
ca.c: 1: 1: avertissement: la définition de données n'a pas de type ou de classe de stockage
ca.c: Dans la fonction 'main':
ca.c: 2: 5: avertissement: déclaration implicite incompatible de la fonction intégrée 'scanf'
ca.c: 3: 7: avertissement: déclaration implicite incompatible de la fonction intégrée 'malloc'
ca.c: 3: 14: avertissement: déclaration implicite incompatible de la fonction intégrée 'strlen'
ca.c: 4: 5: avertissement: déclaration implicite incompatible de la fonction intégrée 'strcat'

josh @ Z1 ~
écho $ 90,11,0,4,0,4,5 | Californie
-bash: ca: commande introuvable

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

luser droog
la source
Agréable. Vous pouvez raser pas mal d'octets en rendant vos intvariables globales et en supprimant #include: r,A,B,C,n,i,j; main(){char *s...
JoeFish
Enregistrer un tas dans vos forboucles:for(;A--;)strcat(s,a);
JoeFish
Et réutilisez Aet Cplus tard pour ne pas avoir à déclarer iou pas Bdu tout. p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Désolé, je m'arrête maintenant :)
JoeFish
Ok, j'ai menti, un de plus. Débarrassez -vous de 2 byes en éliminant --C;: p=malloc((C=strlen(s)-1)+2);. Je pense que le code de golf est plus amusant que de le créer en premier lieu!
JoeFish
Je n'étais pas sûr de supprimer le #includedepuis scanfest variadique. Mais c'est probablement ok car il n'est appelé qu'une seule fois. ... Mon ancienne machine est morte hier, et j'installe toujours Cygwin. J'incorporerai ces changements dès que je pourrai le tester. Merci!
luser droog