Zasymuluj regułę 110

27

Reguła 110 jest automatem komórkowym o kilku interesujących właściwościach. Twoim celem jest zasymulowanie reguły 110 przy użyciu jak najmniejszej liczby znaków.

Dla tych, którzy nie wiedzą, reguła 110 jest symulowana linia po linii w siatce. Każdy kwadrat w linii siatki patrzy na kwadraty powyżej, powyżej po lewej i powyżej po prawej stronie, aby określić, jaka komórka powinna być.

current pattern  111 110 101 100 011 010 001 000
new cell          0   1   1   0   1   1   1   0

Dane wejściowe: liczby od 0 do 39 reprezentujące n-ty kwadrat w górnym wierszu, w dowolnym rozsądnym formacie (ciąg oddzielony przecinkami, lista, argumenty funkcji). Aby uwzględnić języki z jednym indeksem, liczby mogą być również indeksowane z 1 indeksem, a więc mogą zawierać się w przedziale od 1 do 40.

Przykładowe dane wejściowe:

38,39

Wyjście: siatka 40 x 40 reprezentująca działające automaty, w tym pierwszy rząd. Powinieneś zostawić 0 jako pustą i 1 jak każdy widoczny znak drukowania. Dopuszczalne są spacje końcowe, o ile można właściwie rozróżnić rzeczywistą siatkę. Dół siatki może mieć nową linię, ale między liniami siatki nie powinny być puste linie.

Przykładowe dane wyjściowe:

                                  XX
                                 XXX
                                XX X
                               XXXXX
                              XX   X
                             XXX  XX
                            XX X XXX
                           XXXXXXX X
                          XX     XXX
                         XXX    XX X
                        XX X   XXXXX
                       XXXXX  XX   X
                      XX   X XXX  XX
                     XXX  XXXX X XXX

itp.

Uwaga: Podobne pytanie dotyczące automatów komórkowych 1D zostało już zadane, ale mam nadzieję, że przy użyciu tylko jednej reguły można napisać krótsze odpowiedzi.

qwr
źródło
4
Czy wzorce się zawijają (tj. Czy komórka najbardziej po lewej stronie sprawdza komórkę najbardziej po prawej stronie w linii nad nią)?
Ventero
4
Jeśli jest to liczba pojedyncza, to jest to automat komórkowy .
ClickRick
1
Odpowiedzi mogą być ułamkowo krótsze niż Symuluj dowolny automat komórkowy 1D, ponieważ reguła jest zakodowana na sztywno, a nie musi być analizowana z danych wejściowych, ale poza tym odpowiedzi będą takie same. Gdyby to była inna reguła, to istniałaby możliwość oszczędności, ale jak na Ziemi specjalne zastosowanie potężnej reguły Turinga ocaliłoby cokolwiek nad ogólną implementacją?
Peter Taylor
1
@Ventero Nie ma ich w tej wersji.
qwr
1
@BMO to stare pytanie, ale ponieważ obecnie konsensus ma umożliwić elastyczne formaty wejściowe, zmodyfikuję pytanie, aby na to pozwolić
qwr

Odpowiedzi:

8

CJam - 47

S40*l',/{i'!t}/{N40,S3$S++f{>3<2b137Yb='!^}}39*

Używa !komórek „1”.

Wypróbuj na http://cjam.aditsu.net/

Wyjaśnienie:

S40*tworzy ciąg (tablica) z 40 spacjami
l',/czyta linię i dzieli przecinkiem
{…}/wykonuje blok dla każdego elementu (liczby w postaci łańcucha)
- i'!tkonwertuje liczbę na liczbę całkowitą i ustawia pozycję w tym miejscu w poprzednim ciągu (początkowo 40 spacji ) do '!'
W tym momencie uzyskaliśmy pierwszą linię.
{…}39*wykonuje blok 39 razy
- Ndodaje nowy wiersz
- 40,tworzy tablicę [0 1… 39]
- S3$S++kopiuje poprzedni wiersz (pozycja 3 na stosie) i wypełnia go spacją po każdej stronie
- f{…}wykonuje blok dla {każdej liczby od 0 do 39} i {linia wypełniona}
- >3<pobiera wycinek 3 elementów z linii wypełnionej, zaczynając od bieżącego numeru
- 2bkonwertuje z bazy 2; elementy, które kroiliśmy, nie są cyframi 2-podstawowymi, ale znaki są konwertowane na ich wartości ASCII, a „mod 8 to 0 i„! ” mod 8 to 1
- 137Ybkonwertuje 137 na bazę 2 ( Y= 2), otrzymując [1 0 0 0 1 0 0 1], która jest 110 odwrócona i zanegowana (na 8 bitach)
- ='!^otrzymuje odpowiednią cyfrę base-2 ( tablica jest zawijana, więc indeks jest pobierany mod 8) i xor to z '!' znak, w wyniku czego powstaje „!” dla 0 i „” dla 1

aditsu
źródło
17

Ruby, 113 znaków

c=[0]*41
eval"[#{gets}].map{|i|c[i]=1}"+'
c=(0..39).map{|x|putc" X"[u=c[x]]
110[4*c[x-1]+2*u+c[x+1]]}<<0;puts'*40

Pobiera dane wejściowe na standardowe wejście. Aby użyć innej reguły, wystarczy zastąpić 110ostatnią linię dowolną regułą, którą chcesz wypróbować.

Przykład:

$ ruby 110.rb <<< 38,39
                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X
Ventero
źródło
8

Mathematica, 122 bajty

f[a_]:=Riffle[CellularAutomaton[110,Array[If[MemberQ[ToExpression["{"<>a<>"}"],#-1],1,0]&,40],39]/.0->" "/.1->"X","
"]<>""

Tak, możesz postrzegać to jako nadużywanie tej luki , ale a) ta luka jest dość sporna, b) pytanie Automatonu Komórkowego wymaga odpowiedzi Mathematica (zwłaszcza jednej z Reguły 110) ic) Odpowiedź Ruby Ventero jest i tak krótsza, więc nie nie sądzę, aby wyrządzono jakąkolwiek szkodę.

Większość znaków jest wykorzystywana do analizy wejściowej i formatowania wyjściowego. Rzeczywisty automat jest symulowany przy użyciu

CellularAutomaton[110,initialGrid,39]

Wykorzystuje to okresowe warunki brzegowe (więc siatka zawija się).

Martin Ender
źródło
8

Python - 141

i=input()
o=range(40)
l=''.join(' X'[c in i]for c in o)
for r in o:print l;l=''.join('X '[l[c-1:c+2]in('XXX','   ','X  ','','  ')]for c in o)

Uruchom jako np python 110.py <<< 38,39

Alex L.
źródło
3
['X',' ']można zmienić, 'X 'aby zapisać 5 znaków.
Calvin's Hobbies
16
Moim ulubionym owocem jest terazo=range()
kitcar2000
7

q, 67 62 58 bajtów

Zakłada brak zawijania:

{40{not(2 sv'flip 1 0 -1 xprev\:x)in 0 4 7}\@[40#0b;x;~:]}

Stara wersja

{40{not(flip(prev;::;next)@\:x)in 3 cut 111100000b}\@[40#0b;x;not]}
{40{not(flip 1 0 -1 xprev\:x)in 3 3#111100000b}\@[40#0b;x;~:]}
skeevey
źródło
5

Python, 186

def r(s,m=range(40)):
 s=[int(i in s)for i in m]
 for g in m:print''.join([' X'[i]for i in s]);s=[int(not''.join(map(str,s[i-1:i+2]if i else s[:2]))in'111 100 000 00'.split())for i in m]

Przyzwoite, ale prawdopodobnie nie optymalne.

Nie określiłeś sposobu pobierania danych wejściowych, więc właśnie utworzyłem funkcję.

Użyj przykładu:

r ([38,39])

Wydajność:

                                      XX
                                     XXX
                                    XX X
                                   XXXXX
                                  XX   X
                                 XXX  XX
                                XX X XXX
                               XXXXXXX X
                              XX     XXX
                             XXX    XX X
                            XX X   XXXXX
                           XXXXX  XX   X
                          XX   X XXX  XX
                         XXX  XXXX X XXX
                        XX X XX  XXXXX X
                       XXXXXXXX XX   XXX
                      XX      XXXX  XX X
                     XXX     XX  X XXXXX
                    XX X    XXX XXXX   X
                   XXXXX   XX XXX  X  XX
                  XX   X  XXXXX X XX XXX
                 XXX  XX XX   XXXXXXXX X
                XX X XXXXXX  XX      XXX
               XXXXXXX    X XXX     XX X
              XX     X   XXXX X    XXXXX
             XXX    XX  XX  XXX   XX   X
            XX X   XXX XXX XX X  XXX  XX
           XXXXX  XX XXX XXXXXX XX X XXX
          XX   X XXXXX XXX    XXXXXXXX X
         XXX  XXXX   XXX X   XX      XXX
        XX X XX  X  XX XXX  XXX     XX X
       XXXXXXXX XX XXXXX X XX X    XXXXX
      XX      XXXXXX   XXXXXXXX   XX   X
     XXX     XX    X  XX      X  XXX  XX
    XX X    XXX   XX XXX     XX XX X XXX
   XXXXX   XX X  XXXXX X    XXXXXXXXXX X
  XX   X  XXXXX XX   XXX   XX        XXX
 XXX  XX XX   XXXX  XX X  XXX       XX X
XX X XXXXXX  XX  X XXXXX XX X      XXXXX
XXXXXX    X XXX XXXX   XXXXXX     XX   X
Hobby Calvina
źródło
Ja określiłem dane wejściowe: w twoim przypadku będziesz musiał użyć input () i sformatować dane wejściowe, jak określono w oryginalnym poście.
qwr
5

Mathematica, 113 znaków

Kolejna odpowiedź Mathematica za pomocą CellularAutomaton.

Print@@" "["X"][[#]]&/@CellularAutomaton[110,SparseArray[#+1->1&/@ImportString[InputString[],"CSV"][[1]],40],39];
alephalpha
źródło
Ciekawe, jak " "["X"][[#]]&działa?
Martin Ender
@ m.buettner " "["X"][[1]]is "X". " "["X"][[0]]zwraca głowę " "["X"], a mianowicie " ".
alephalpha
Rozumiem. Więc to jest po prostu zapisywanie postaci do list. To naprawdę sprytne. Myślę, że możesz dodać to do codegolf.stackexchange.com/questions/12900/...
Martin Ender
4

C - 178

Ten kod zależy od faktu, że każdy wiersz w macierzy jest przechowywany w ciągłej pamięci. Ponadto nie drukuje pierwszego wiersza, ale drukuje kolejne 40, ponieważ reguły określały tylko siatkę 40x40.

Z naciskiem tylko na czytelność, liczba bajtów zawiera tylko niezbędny kod.

a[41][42],i,j,*t;
main(){
    while(scanf("%d,",&j)>0)
        a[i][j]=1;
    for(;i<40;i++,puts(""))
        for(j=0;++j<40;)
            t=&a[i][j],
            putchar((*(t+42)=1&(110>>(*(t+1)?1:0)+(*t?2:0)+(*(t-1)?4:0)))?88:32);
}
Allbeert
źródło
3

Lua - 351

Nie jest to idealny język do gry w golfa.

s,n,t,u=arg[1],{},table.remove,table.insert
for i=1,40 do u(n,i,'.') end
for i in s:gmatch("%d+")do u(n,i,'x');t(n)end
function a(b) c="";for i=1,40 do c=c..b[i] end;print(c);return c end
for i=1,40 do z= n[40]..a(n)..n[1];for k=2,41 do y=string.sub(z,k-1,k+1);if y=="xxx"or y=="x.." or y=="..." then u(n,k-1,'.')else u(n,k-1,'x')end;t(n)end end
AndoDaan
źródło
1
do u(n,i,'x')to celowe, prawda?
Stan Strum
3

Haskell , 175 170 169 136 127 127 124 bajtów

−9 bajtów dzięki @bmo

t(a:b:r:_)=mod(b+r+b*r+a*b*r)2
w%a=take 40.map w.iterate a
d l=t%tail$0:l++[0]
f l=map(" #"!!)%d$(fromEnum.(`elem`l))%succ$0

Wypróbuj online!

FrownyFrog
źródło
3

Haskell , 135 131 130 bajtów

-1 bajt dzięki Ørjan Johansen (zmiana układu take 40)

Zupełnie inne podejście do odpowiedzi FrownyFrog, ale o tej samej długości:

(a?b)r=mod(b+r+b*r+a*b*r)2
r x=0:(zipWith3(?)x=<<tail$tail x++[0])
f y=take 40$map(" o"!!)<$>iterate r[sum[1|elem i y]|i<-[0..40]]

1

Wyjaśnienie

4101

f y=                               [sum[1|elem i y]|i<-[0..40]]

40

    take 40$              iterate r

01

            map(" o"!!)<$>

r110zipWith3(?)

r x=0:(zipWith3(?)x=<<tail$tail x++[0])

(?)Operator jest najbardziej interesująca część rozwiązania: Wcześniej użyłem logiczną zasadę wygenerowany z mapą Karnaugh, ale okazuje się, że jest jeszcze bardziej zwięzły sposób:

(a?b)r=mod(b+r+b*r+a*b*r)2
ბიმო
źródło
1
Zapisz bajt, wstawiając take 40$wcześniej map(" o"!!)<$>.
Ørjan Johansen
3

Łuska , 31 28 bajtów

Hah, Łuska bije Galaretkę!

†!¨↑¨↑40¡ȯẊȯ!ḋ118ḋėΘ`:0M#ŀ40

Wypróbuj online!

Wyjaśnienie i nieprzygotowany

Przed dodaniem wyjaśnienia pozwól mi to trochę odhaczyć. Najpierw usuńmy różne kompozycje, dodajmy wyraźne nawiasy i rozpakuj ¨↑¨ciąg. Także niech zastąpić 40z 4bardziej czytelnego wyjaśnienia:

†!"t "↑4¡(Ẋ(!ḋ118ḋė)Θ`:0)M#ŀ4  -- example input: [3]
                           ŀ4  -- lower range of 4: [0,1,2,3]
                         M     -- map over left argument
                          #    -- | count in list
                               -- : [0,0,0,1]
        ¡(              )      -- iterate the following indefinitely (example with [0,1,1,1])
                     `:0       -- | append 0: [0,1,1,1,0]
                    Θ          -- | prepend 0: [0,0,1,1,1,0]
          Ẋ(       )           -- | map over adjacent triples (example with  1 1 0
                  ė            -- | | create list: [1,1,0]
                 ḋ             -- | | convert from base-2: 6
                               -- | | convert 118 to base-2: [1,1,1,0,1,1,0]
                               -- | | 1-based index: 1
                               -- | : [1,1,0,1]
                               -- : [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1],[1,1,1,1],[1,0,0,1],...]
      ↑4                       -- take 4: [[0,0,0,1],[0,0,1,1],[0,1,1,1],[1,1,0,1]]
†                              -- deep map the following (example with [1,1,0,1])
 !"t "                         -- | use each element to index into "t ": "tt t"
                               -- : ["   t","  tt"," ttt","tt t"]
ბიმო
źródło
2

Java, 321 znaków

Dane wejściowe przekazywane na przykład jako argument z wiersza poleceń java R 38,39

Nigdy nie pisałem bardziej zaciemnionego kodu Java :-)

class R{public static void main(String[]a) {
Integer s=40;boolean[]n,o=new boolean[s];
for(String x:a[0].split(","))o[s.valueOf(x)]=s>0;
for(Object b:o){n=o.clone();
for(int j=0;j<s;j++){
boolean l=j>1&&o[j-1],r=o[j],c=j+1<s&&o[j+1];
n[j]=!(l&c&r|l&!c&!r|!(l|c|r));
System.out.print((r?"X":" ")+(j>s-2?"\n":""));
}o=n;}}}
Tomáš Dvořák
źródło
2

Aktualizacja: Poprawny przykład wyjścia tutaj (z 40 wierszami nie 50): Nowe wyjście poniżej (usunięte poprzednie dla zwięzłości):

                                      xx
                                     xxx
                                    xx x
                                   xxxxx
                                  xx   x
                                 xxx  xx
                                xx x xxx
                               xxxxxxx x
                              xx     xxx
                             xxx    xx x
                            xx x   xxxxx
                           xxxxx  xx   x
                          xx   x xxx  xx
                         xxx  xxxx x xxx
                        xx x xx  xxxxx x
                       xxxxxxxx xx   xxx
                      xx      xxxx  xx x
                     xxx     xx  x xxxxx
                    xx x    xxx xxxx   x
                   xxxxx   xx xxx  x  xx
                  xx   x  xxxxx x xx xxx
                 xxx  xx xx   xxxxxxxx x
                xx x xxxxxx  xx      xxx
               xxxxxxx    x xxx     xx x
              xx     x   xxxx x    xxxxx
             xxx    xx  xx  xxx   xx   x
            xx x   xxx xxx xx x  xxx  xx
           xxxxx  xx xxx xxxxxx xx x xxx
          xx   x xxxxx xxx    xxxxxxxx x
         xxx  xxxx   xxx x   xx      xxx
        xx x xx  x  xx xxx  xxx     xx x
       xxxxxxxx xx xxxxx x xx x    xxxxx
      xx      xxxxxx   xxxxxxxx   xx   x
     xxx     xx    x  xx      x  xxx  xx
    xx x    xxx   xx xxx     xx xx x xxx
   xxxxx   xx x  xxxxx x    xxxxxxxxxx x
  xx   x  xxxxx xx   xxx   xx        xxx
 xxx  xx xx   xxxx  xx x  xxx       xx x
xx x xxxxxx  xx  x xxxxx xx x      xxxxx
xxxxxx    x xxx xxxx   xxxxxx     xx   x

Układając kolejną łamigłówkę, nauczyłem się czegoś ciekawego na temat zagnieżdżania instrukcji w pętlach for w php i nagle stały się one znacznie bardziej złożone, niż początkowo myślałem. Kiedy mam czas, wydaje mi się, że mogę znacznie pokonać ten wynik. Na razie pozostaje jednak bez zmian na niekonkurencyjnym 408.


Moja wersja PHP 408 znaków:

To była świetna łamigłówka. Spędziłem też całe wieki, grając z wejściami, ponieważ są to fascynujące rzeczy, trzeba powiedzieć. W każdym razie tutaj jest moja wersja PHP (która nie jest tak dobra, jak niektóre z opublikowanych odpowiedzi, ale jest kompletna. Na 0 pozycji tylko powyżej i powyżej prawej, na 39 pozycji tylko powyżej i powyżej lewej, tzn. Bez zawijania. Więc tutaj jest moja wersja:

<?php $a='38,39';$b='';$d=explode(',',$a);for($i=0;$i<40;++$i){$c=' ';
foreach($d as $k=>$v){if($v == $i){$c='x';}}$b.=$c;}echo $b."\n";
for($x=1;$x<41;++$x){$o='';for($i=1;$i<41;++$i){if(($i>1)AND(substr($b,$i-2,1)=='x')){
$l=1;}else{$l=0;}if((substr($b,$i-1,1))=='x'){$v=1;}else{$v=0;}if((substr($b,$i,1))=='x'){
$r=1;}else{$r=0;}if((($l+$v+$r)==2)OR(($v+$r)==1)){$o.='x';}else{$o.=' ';}}
echo $o."\n";$b=$o;}?>

Możesz go zobaczyć i uruchomić tutaj: http://codepad.org/3905T8i8

Dane wejściowe są łańcuchem wejściowym na początku jako $ a = '38, 39 ';

Dane wyjściowe są następujące:

xx removed as was too long originally - had 50 lines, not 40 xx

Mam nadzieję że ci się spodoba!!!

PS Musiałem dodać kilka podziałów linii do kodu, abyś mógł zobaczyć wszystko i nie rozciągać go na stronę za pomocą paska przewijania.

Paul Drewett
źródło
Twój wynik ma 50 linii
aditsu
Ach, to dlatego, że bawiłem się tym, kiedy skończyłem i zobaczyłem, co się stało. Nieznaczne modyfikowanie reguł ma tak interesujący wpływ. Zresztą zmieniłem go teraz na 40 i przepraszam, że tego przegapiłem.
Paul Drewett
Możesz także zmienić wyjście: p
aditsu
Poprawiono dane wyjściowe i dodano nowe łącze do klawiatury kodowej o poprawnej wartości. Jeszcze raz dziękuję.
Paul Drewett
2

Stax , 24 bajty CP437

╦♥µ╤u{£┬íQ<;▀ΦΣ╢╕╚äZ↕áû↑

Uruchom i debuguj online!

Używa punktu kodowego 1 w CP437 dla komórek „1”.

Doskonałe etui, aby pokazać moc tego języka.

Wyjaśnienie

Używa do rozpakowania wersji (29 bajtów).

0]40X*,1&xDQ0]|S3B{:b^374:B@m
0]40X*                           Prepare a tape with 40 cells
      ,1&                        Assign 1 to the cells specified by the input
         xD                      Repeat the rest of the program 40 times
           Q                     Output current tape
            0]|S                 Prepend and append a 0 cell to it
                3B               All runs of length 3
                  {         m    Map each run with block
                   :b            Convert from binary
                     ^           Increment (call this value `n`)
                      374:B      The binary representation of 374
                                 [1,0,1,1,1,0,1,1,0]
                                 which is `01101110` reversed and prepended a 1
                           @     Element at 0-based index `n`
Weijun Zhou
źródło
1

K (ngn / k) , 44 35 bajtów

{"X "39{(2\145)@2/'3'1,x,1}\^x?!40}

Wypróbuj online!

{ } funkcja z argumentem x

!40 lista liczb wewnętrznych od 0 do 39

x?znajdź swoje indeksy w x, użyj 0N(„liczba całkowita null”) dla nie znaleziono

^które z nich są zerami? to daje nam wkład, zanegowany

39{ }\ aplikuj 39 razy, zbierając wyniki pośrednie na liście

1,x,1 otaczaj listę 1s (zanegowane 0)

3' trzy kolejne pozycje

2/' dekodowanie binarne

@ używać jako wskaźników w ...

2\145 kod binarny 145 (negowane bity 110)

"X "na koniec użyj macierzy 40x40 jako wskaźników w łańcuchu "X "( @tutaj jest to domniemane)

ngn
źródło