Symuluj dowolny automat komórkowy 1D


14

Wyzwanie

Masz napisać kompletny program, który pobiera siedem liczb ze STDIN i drukuje dwuwymiarową historię automatu komórkowego (CA) do STDOUT. To jest kod golfowy.

Formatowanie danych wejściowych Będzie to siedem liczb całkowitych / ciągów oddzielonych przecinkami. Pierwsza liczba to numer reguły zgodnie z kodem Wolfram (standardowa nazwa każdej reguły). Drugi to początkowa konfiguracja początkowa. Trzeci i czwarty opisują jaki wzorzec i ile razy należy go dołączyć po lewej stronie początkowej konfiguracji. jako wyściółka. Piąta i szósta robią to samo dla prawej strony. Ostatnia liczba to liczba pokoleń do uruchomienia symulacji.

Przykładem jest dane wejściowe 90,11,0,4,0,4,5. To powinno powiedzieć Twojemu programowi, że korzystasz z reguły 90 . Powinien także powiedzieć programowi, że chcesz, aby początkowa konfiguracja była 11z łańcuchem 0dołączonym 4 razy na obu końcach, więc rzeczywisty wzorzec początkowy to 0000110000. Informuje również twój program o uruchomieniu tej symulacji przez 5 pokoleń.

Dane wyjściowe Twój program powinien drukować całą tablicę komórek każdego pokolenia (oddzielonych znakami nowej linii), tak aby dane wyjściowe były schematem czasoprzestrzennym urzędu certyfikacji. Dla każdego pokolenia stan każdej komórki jest określony przez jej stan i stany komórek po lewej i prawej stronie, zgodnie z regułą podaną jako dane wejściowe. Symulacja powinna owijać się wokół krawędzi. Pierwszą drukowaną rzeczą powinna być tablica początkowa jako gen. 0.

Dane wejściowe 90,11,0,4,0,4,5powinny skutkować następującymi danymi wyjściowymi tak dokładnie, jak to możliwe.

0000110000
0001111000
0011001100
0111111110
1100000011
0110000110

Zauważ, że stan początkowy nie jest uwzględniony w pięciu pokoleniach. Zauważ również, że symulacja owija się wokół krawędzi.

Więcej przykładów

Wejście:

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

wynik:

0101110001
1011101000
0111010100
0110101010
0101010101

Wejście:

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

wynik:

10110
00000
00000

Więcej informacji o tym, jak działa 1D CA i jak są one ponumerowane


Dobra robota w przypadku włączenia reguły 0 jako przypadku testowego.
Peter Taylor,

Fascynuje mnie to, że reguła 90 to Uszczelka Sierpińskiego. Zwłaszcza, że ​​był to element testów, które przeprowadziłem dla innego projektu Codegolf .
JoeFish,

@JoeFish To twój obraz skłonił mnie do wypróbowania tego. Chciałem uzyskać odpowiedź 8086 - zabić 2 ptaki - ale prawdopodobnie wymagałoby to operacji łańcuchowych, więc mój emulator nie byłby w stanie jej uruchomić (jeszcze).
luser droog

Odpowiedzi:


5

Golfscript, 77 73 70 znaków

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

Dzięki @Howard, który wskazał, jak zapisać 4 znaki.


Możesz zapisać oczywisty 48--> 1&i myślę, że jeszcze trzy. Możesz pominąć )przed blokiem (nie zwiększać licznika), a zatem zapisać również dwa ostatnie wyskoki.
Howard,

@ Howard, dzięki. Te trzaski na końcu były przydatne we wcześniejszej iteracji, ale masz rację, że wyeliminowanie ich ma teraz sens.
Peter Taylor,

5

APL (153 znaki)

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

I w mniej czytelnej, nieco krótszej formie:

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

Przykład:

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

Jestem pewien, że jest miejsce na ulepszenia (nawet napisałem kilka zmian podczas pisania tego postu!), Ale niektóre z nich mogą wymagać fundamentalnych zmian i nie mogę dłużej patrzeć na APL. Stosowanym tutaj wariantem APL jest Dyalog APL .


4

Rubin, 165 159 znaków

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

Edycja: Znalazłem miejsca na małe ulepszenia.

Przykładowy przebieg:

> 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

3

C 303 305 301 294 292

305 Edycja: ups. Zapomniałem o tymcalloc() potrzeba dwóch argumentów. Wysadzało to przy większym wejściu.

301 Edycja: Ah HA! Użyłem mojegocalloc()Użyłem boo-boo, aby zaoszczędzić 2 bajty, zwiększając rozmiar bloku żądanej pamięci.

294 Edycja: Złam 300! Wyeliminowany jeden zstrcat() i poprawiłem kilka pętli. Muszę użyć maksymalnego chrupka, co jest równie zabawne w mówieniu, jak używanie.

292 Edycja: Nie potrzebowałem +2 przydziału pamięci.

I używany odpowiedź luser Droog jest jako idea bazowej, ale zmienił się algorytm pakowania, a także wiele szczypanie i faktoringu ze stałych.

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

zrzut ekranu 1

zrzut ekranu2


1
Zapomniałeś, żeby to się zaczęło C,A,! :)
luser droog

dla dużej ilości pamięci, co powiesz na brk()? to p=s+C+1;gdzieś
luser droog

1
+1 ponownie za użycie +++!
luser droog

Ha ha! Zmień wszystko %[01], aby %s! -9 (... wiele lat później)
luser droog

1
@luserdroog to nie działa, ponieważ% s jest zachłanny i zjada przecinki oraz inne cyfry.
JoeFish

2

C (487 484 418 z usuniętymi spacjami)

* Upuszczono 66 z pomocą JoeFisha *

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

maszynopis

josh @ Z1 ~
$! m
zrobić ok
cc ca.c -o ca
ca.c: 1: 1: ostrzeżenie: definicja danych nie ma typu ani klasy pamięci
ca.c: W funkcji „main”:
ca.c: 2: 5: ostrzeżenie: niekompatybilna niejawna deklaracja wbudowanej funkcji „scanf”
ca.c: 3: 7: ostrzeżenie: niekompatybilna niejawna deklaracja wbudowanej funkcji „malloc”
ca.c: 3: 14: ostrzeżenie: niekompatybilna niejawna deklaracja wbudowanej funkcji „strlen”
ca.c: 4: 5: ostrzeżenie: niekompatybilna niejawna deklaracja wbudowanej funkcji „strcat”

josh @ Z1 ~
Echo $ 90,11,0,4,0,4,5 | ca
-bash: ca: polecenie nie zostało znalezione

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


Ładny. Możesz ogolić sporo bajtów, intustawiając zmienne globalne i usuwając #include: r,A,B,C,n,i,j; main(){char *s...
JoeFish,

Zapisz forfor(;A--;)strcat(s,a);
sporo

I ponowne użycie, Aa Cpóźniej, abyś nie musiał się deklarować iani Bwcale. p=malloc((C=strlen(s))+1); --C; strcpy(p,s); for(A=0;A<n;A++){Przepraszam, przestanę teraz :)
JoeFish,

Ok kłamałem jeszcze raz. Pozbądź 2 pożegnań eliminując --C;: p=malloc((C=strlen(s)-1)+2);. Myślę, że kod do gry w golfa jest fajniejszy niż wymyślanie go w pierwszej kolejności!
JoeFish,

Nie byłem pewien o usunięcie #include, ponieważ scanfjest o zmiennej liczbie argumentów. Ale prawdopodobnie jest w porządku, ponieważ jest wywoływany tylko raz. ... Moja stara maszyna zmarła wczoraj, a ja wciąż instaluję Cygwin. Uwzględnię te zmiany, jak tylko będę mógł je przetestować. Dzięki!
luser droog
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.