Zmień zasady życia

15

Żywotny automat komórkowy jest automatem komórkowym podobnym do Conway's Game of Life, ponieważ działa na (teoretycznie) nieskończenie dużej kwadratowej siatce, gdzie każda komórka ma dokładnie 8 sąsiadów i jest jednym z 2 stanów, mianowicie żywym i martwym .

Jednak te podobne do wersji wersje różnią się w kluczowy sposób: zasady, aby dana komórka ożyła i zasady, aby dana komórka przetrwała do następnej generacji.

Na przykład klasyczna gra w życie stosuje regułę B3/S23, co oznacza, że ​​3 żywe komórki rodzą nową, a 2 lub 3 żyjących sąsiadów, aby przeżyć. W przypadku tego wyzwania założymy, że sąsiedzi się nie uwzględniają, więc każda komórka ma dokładnie 8 sąsiadów.

Twoim zadaniem jest, biorąc pod uwagę konfigurację początkową, regułę urodzenia, regułę przeżycia i dodatnią liczbę całkowitą (liczbę pokoleń do uruchomienia), przeprowadzić symulację automatu podobnego do Życia, stosując te reguły dla liczby pokoleń podanych w możliwie najkrótszym kodzie . Konfiguracja początkowa będzie macierzą kwadratową / tablicą 2-wymiarową lub łańcuchem wielowierszowym, do wyboru. Pozostałe mogą być podane w dowolnym rozsądnym formacie i metodzie.

Na przykład, jeśli reguła narodzin była 12345678(dowolni żyjący sąsiedzi), reguła przetrwania była, 2357a konfiguracja początkowa była

0 0 0 0 0
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0

będą następne dwa pokolenia

Generation 1:           Generation 2:

0 0 0 0 0               1 1 1 1 1
0 1 1 1 0               1 1 0 1 1
0 1 0 1 0               1 0 1 0 1
0 1 1 1 0               1 1 0 1 1
0 0 0 0 0               1 1 1 1 1

Gdyby liczba podanych pokoleń wynosiła 10, wynikiem byłoby coś podobnego do

0 1 1 1 0
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
0 1 1 1 0

Nie musisz obsługiwać zmian, które zachodzą poza granicami podanymi przez macierz wejściową, jednak wszystkie komórki poza macierzą zaczynają działać martwe. Dlatego macierz wejściowa może mieć dowolny rozmiar, do maksymalnej wartości obsługiwanej przez Twój język. Nie musisz generować tablicy między pokoleniami.

To jest więc wygrywa najkrótszy kod.

Przypadki testowe

Wykorzystują one B/Szapis do wskazania zastosowanych reguł

B2/S2, generations = 100konfiguracja:

1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0

Wynik:

0 0 0 0 0 0 0 0
0 1 0 0 0 0 1 0
1 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

B1357/S2468, generations = 12konfiguracja:

1 0 1 0 1 0
0 1 1 0 1 0
1 0 0 0 0 0
0 0 0 0 0 1
1 1 1 1 1 0
0 1 1 0 0 1

Wynik:

0 1 0 0 0 0
0 1 1 1 1 0
0 1 0 1 1 0
1 1 1 0 0 0
0 0 1 1 1 0
0 1 1 0 0 0

Jeśli chcesz wygenerować więcej przypadków testowych, możesz użyć tego wspaniałego symulatora. Pamiętaj, aby ograniczyć rozmiar planszy

Cairney Coheringaahing
źródło
Czy symulacja jest toroidalna?
Erik the Outgolfer,
@EriktheOutgolfer nie, ponieważ matryca ma (teoretycznie) nieskończony rozmiar
Cairney Coinheringaahing
Czy możemy również założyć, że podana macierz jest kwadratowa?
Erik the Outgolfer,
2
@EriktheOutgolfer "nieskończenie duża kwadratowa siatka"
caird coinheringaahing
Ale to nie znaczy, że możesz założyć, że ... wejdzie do edycji.
Erik the Outgolfer

Odpowiedzi:

9

MATL , 24 23 bajty

xx:"tt3Y6Z+1Gm<8M2Gmb*+

Dane wejściowe to:

  • Tablica z regułą narodzin
  • Tablica z regułą przeżycia
  • Liczba pokoleń
  • Macierz z początkową konfiguracją komórki, wykorzystująca ;jako separator wierszy.

Wypróbuj online! Lub zobacz przypadki testowe: 1 , 2 .

Jeszcze przez kilka bajtów widać ewolucję w sztuce ASCII .

Wyjaśnienie

xx      % Take two inputs implicitly: birth and survival rules. Delete them
        % (but they get copied into clipboard G)
:"      % Take third input implicitly: number of generations. Loop that many times
  tt    %   Duplicate twice. This implicitly takes the initial cell configuration
        %   as input the first time. In subsequent iterations it uses the cell 
        %   configuration from the previous iteration
  3Y6   %   Push Moore neighbourhood: [1 1 1; 1 0 1; 1 1 1]
  Z+    %   2D convolution, maintaining size
  1G    %   Push first input from clipboard G: birth rule
  m     %   Ismember: gives true for cells that fulfill the birth rule
  <     %   Less than (element-wise): a cell is born if it fulfills the birth rule
        %   *and* was dead
  8M    %   Push result of convolution again, from clipboard M
  2G    %   Push second input from clipboard G: survival rule
  m     %   Ismember: gives true for cells that fulfill the survival rule
  b     %   Bubble up the starting cell configuration
  *     %   Multiply (element-wise): a cell survives if it fulfills the survival
        %   rule *and* was alive
  +     %   Add: a cell is alive if it has been born or has survived, and those
        %   are exclusive cases. This produces the new cell configuration
        % Implicit end loop. Implicit display
Luis Mendo
źródło
Czy można zapisać bajty, zmieniając kolejność danych wejściowych? xxNa początku wydaje się nieco rozrzutny do mnie ...
Eryk Outgolfer
@EriktheOutgolfer Nie wiem jak. Muszę usunąć pierwsze dwa, aby później ponownie użyć ich kilka razy (po jednym na iterację), a pozostałe dane są już domyślnie ukryte
Luis Mendo,
Och, więc „usunięcie” danych wejściowych dodaje je do jakiejś listy danych wejściowych?
Erik the Outgolfer,
@EriktheOutgolfer Tak. Wejście MATL jest interaktywne, co oznacza, że ​​program nie wie z góry, ile jest danych wejściowych. W tym przypadku usunięcie z pustego stosu powoduje niejawne pobranie danych wejściowych. Po pobraniu każde wejście jest kopiowane do schowka G i można je później odzyskać.
Luis Mendo,
3

Wolfram Language (Mathematica) , 144 122 bajtów

CellularAutomaton[{Tr[2^#&/@Flatten@MapIndexed[2#+2-#2[[1]]&,{#2,#3},{2}]],{2,{{2,2,2},{2,1,2},{2,2,2}}},{1,1}},#,{{#4}}]&

Wypróbuj online!

Przykładowe użycie:

%[RandomInteger[1, {10, 10}], {2, 3}, {3}, 5]

używa losowej siatki 10x10 na początek, przeżywa z 2 lub 3 sąsiadami, rodzi się z 3 sąsiadami, wyniki fabuły przy 5 iteracjach.

Kelly Lowder
źródło
Szkoda, że ​​wbudowany jest tylko jednowymiarowy (popraw mnie, jeśli się mylę)
Zacharý,
Używam wbudowanego „CellularAutomaton” z 9-sąsiadową regułą totalistyczną. Znaczna część kodu przekształca dane dotyczące przeżycia / urodzenia w liczbę reguł.
Kelly Lowder
1

R , 256 bajtów

function(x,B,S,r){y=cbind(0,rbind(0,x,0),0)
n=dim(y)[1]
z=c(1,n)
f=function(h){w=-1:1
b=h%%n+1
a=(h-b+1)/n+1
'if'(a%in%z|b%in%z,0,sum(x[w+b,w+a])-x[b,a])}
while(r){x=y
for(i in 1:n^2){u=f(i-1)
y[i]=u%in%B
y[i]=(y[i]&!x[i])|(x[i]&(u%in%S))}
r=r-1}
y[-z,-z]}

Wypróbuj online!

Niestety nie wygląda to tak golfowo, jak się spodziewałem.

Dane wejściowe : macierz R i parametry wyzwania. Wyjście : macierz po generacjach R.

Algorytm wypełnia macierz zerami, aby obsłużyć granice. Następnie, iteracyjnie: 1) stosuje regułę narodzin i 2) zabija istniejące wcześniej komórki, które nie przeszły reguły przetrwania. Padding jest usuwany podczas powrotu.

Nie dotyczy
źródło
niezła liczba bajtów!
Giuseppe,
Udało mi się dostać do 217 bajtów, ale jeśli znajdziemy dokładnie jeszcze jednego golfa, możemy uzyskać 216co najmniej sześcian ...
Giuseppe,
1

Python 2 , 156 149 146 bajtów

lambda R,g,c:g and f(R,g-1,[[`sum(sum(l[y+y/~y:y+2])for l in c[x+x/~x:x+2])-c[x][y]`in R[c[x][y]]for y,_ in e(c)]for x,_ in e(c)])or c
e=enumerate

Wypróbuj online!

Pobiera dane wejściowe:

  • Rules: [birth,survial]rządzi jako lista string. np. ( ['135','246'])
  • generacje: int
  • ckonfiguracja: kwadratowa tablica 2D 1/0lubTrue/False

Zwraca tablicę 2d z True/False

TFeld
źródło