Simulieren Sie einen beliebigen 1D-Mobilfunkautomaten

14

Die Herausforderung

Sie müssen ein vollständiges Programm schreiben, das aus STDIN sieben Zahlen entnimmt und die zweidimensionale Historie des Zellularautomaten (CA) an STDOUT ausgibt. Das ist Code Golf.

Eingabeformatierung der Eingabe handelt es sich um sieben durch Kommas getrennte Ganzzahlen / Zeichenfolgen. Die erste Zahl ist die Nummer der Regel gemäß Wolfram-Code (der Standardname für jede Regel). Die zweite ist die anfängliche Startkonfiguration. Die dritten und vierten beschreiben, welches Muster und wie oft es links von der Startkonfiguration angehängt werden soll. als Polsterung. Der fünfte und sechste machen dasselbe für die rechte Seite. Die letzte Zahl ist die Anzahl der Generationen, um die Simulation auszuführen.

Ein Beispiel für eine Eingabe ist also 90,11,0,4,0,4,5. Dies sollte Ihrem Programm mitteilen, dass Sie Regel 90 ausführen . Es sollte dem Programm auch mitteilen, dass bei der Erstkonfiguration 11die Zeichenfolge 0viermal an beide Enden angehängt werden soll, sodass das eigentliche Startmuster lautet 0000110000. Außerdem wird Ihr Programm angewiesen, diese Simulation für 5 Generationen auszuführen.

Ausgabe Ihr Programm sollte das gesamte Array von Zellen jeder Generation (durch Zeilenumbrüche getrennt) drucken, damit die Ausgabe das Raum-Zeit-Diagramm der Zertifizierungsstelle ist. Für jede Generation wird der Zustand jeder Zelle durch ihren Zustand und die Zustände der Zellen unmittelbar links und rechts gemäß der als Eingabe bereitgestellten Regel bestimmt. Die Simulation sollte sich um die Kanten wickeln. Das erste, was gedruckt wird, sollte das Startarray als gen sein. 0.

Die Eingabe 90,11,0,4,0,4,5sollte so genau wie möglich zur folgenden Ausgabe führen.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

Beachten Sie, dass der Ausgangszustand in den fünf Generationen nicht enthalten ist. Beachten Sie auch, dass sich die Simulation um die Kanten schlängelt.

Mehr Beispiele

Eingang:

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

Ausgabe:

0101110001
1011101000
0111010100
0110101010
0101010101

Eingang:

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

Ausgabe:

10110
00000
00000

Weitere Informationen zur Funktionsweise und Nummerierung von 1D CAs

PhiNotPi
quelle
Gut gemacht, um Regel 0 als Testfall aufzunehmen.
Peter Taylor
Ich bin fasziniert, dass Regel 90 eine Sierpinski-Dichtung ist. Zumal das Teil der Tests war, die ich für ein anderes Codegolf-Projekt durchgeführt habe .
JoeFish
@JoeFish Es war dein Bild, das mich veranlasste, dieses auszuprobieren. Ich wollte eine 8086-Antwort machen - 2 Vögel töten - aber es würde wahrscheinlich Zeichenkettenoperationen erfordern, damit mein Emulator es (noch) nicht ausführen kann.
Luser Droog
Jemand hat es schon getan
luser droog

Antworten:

5

Golfscript, 77 73 70 Zeichen

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

Vielen Dank an @Howard, der darauf hingewiesen hat, wie man 4 Zeichen spart.

Peter Taylor
quelle
Sie können eine offensichtliche speichern 48--> 1&und ich denke auch drei weitere. Sie können )vor dem Block weglassen (den Zähler nicht erhöhen) und somit auch die letzten beiden Pops speichern.
Howard
@Howard, danke. Diese Pops am Ende waren in einer früheren Iteration nützlich, aber Sie haben Recht, dass es jetzt Sinn macht, sie zu eliminieren.
Peter Taylor
5

APL (153 Zeichen)

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

Und in weniger lesbarer, etwas kürzerer Form:

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

Beispiel:

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

Ich bin sicher, dass es Raum für Verbesserungen gibt (ich habe sogar ein paar Änderungen gefunden, als ich diesen Beitrag geschrieben habe!), Aber einige davon könnten grundlegende Änderungen beinhalten, und ich kann es nicht mehr ertragen, APL anzustarren. Die hier verwendete Variante von APL ist Dyalog APL .

Dillon Cower
quelle
4

Ruby, 165 159 Zeichen

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

Bearbeiten: Ich habe einige Stellen für kleine Verbesserungen gefunden.

Beispiellauf:

> 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
quelle
3

C 303 305 301 294 292

305 Edit: oops. Ich habe vergessen, dass calloc()das zwei Argumente erfordert. Es explodierte bei größerem Input.

301 Edit: Ah HA! Benutzt my calloc()boo-boo, um 2 weitere Bytes zu sparen, indem die Blockgröße des angeforderten Speichers erhöht wird.

294 Edit: 300 gebrochen! Beseitigte eines der strcat()s und optimierte ein paar Schleifen. Ich muss maximal munch verwenden, was genauso viel Spaß macht wie use.

292 Edit: Benötigte die +2Zuweisung im Speicher nicht.

Ich benutzte die Antwort von luser droog als Grundidee, änderte aber den Wrapping-Algorithmus sowie viele Optimierungen und Faktorisierungen von Konstanten.

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
quelle
1
Sie haben vergessen, es zu starten C,A,! :)
Luser Droog
Was ist mit viel Gedächtnis brk()? dann p=s+C+1;irgendwo.
Luser Droog
1
Nochmals +1 für die Verwendung +++!
Luser Droog
Haha! Ändern Sie alle %[01]zu %s! -9 (... viele Jahre später)
luser droog
1
@luserdroog Das funktioniert nicht, weil% s gierig ist und auch Kommas und andere Ziffern frisst.
JoeFish
2

C (487 484 418 mit Leerzeichen entfernt)

* Fiel 66 mit Hilfe von 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);
}

Typoskript

Josh @ Z1 ~
$! m
machen ca
cc ca.c -o ca
ca.c: 1: 1: Warnung: Die Datendefinition hat keinen Typ oder keine Speicherklasse
ca.c: In der Funktion 'main':
ca.c: 2: 5: Warnung: Inkompatible implizite Deklaration der eingebauten Funktion 'scanf'
ca.c: 3: 7: Warnung: Inkompatible implizite Deklaration der eingebauten Funktion 'malloc'
ca.c: 3: 14: Warnung: Inkompatible implizite Deklaration der eingebauten Funktion 'strlen'
ca.c: 4: 5: Warnung: Inkompatible implizite Deklaration der eingebauten Funktion 'strcat'

Josh @ Z1 ~
$ echo 90,11,0,4,0,4,5 | ca
-bash: ca: Befehl nicht gefunden

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

Luser Droog
quelle
Nett. Sie können einige Bytes rasieren, indem Sie Ihre intVariablen global machen und #includer,A,B,C,n,i,j; main(){char *s...
Folgendes
Speichern Sie einen Haufen in Ihren forLoops:for(;A--;)strcat(s,a);
JoeFish
Und wiederverwenden Aund Cspäter, damit Sie nicht ioder Büberhaupt nicht deklarieren müssen . p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Sorry, ich
höre
Ok, ich habe noch einen gelogen. Lassen Sie sich von 2 byes los durch die Beseitigung --C;: p=malloc((C=strlen(s)-1)+2);. Ich denke, Golfcode macht mehr Spaß, als ihn überhaupt zu erfinden!
JoeFish
Ich war mir nicht sicher, ob ich das #includeDa scanfentfernen sollte. Aber es ist wahrscheinlich in Ordnung, da es nur einmal aufgerufen wird. ... Meine alte Maschine ist gestern gestorben und ich installiere immer noch Cygwin. Ich werde diese Änderungen übernehmen, sobald ich sie testen kann. Vielen Dank!
Luser Droog