Animuj tandetne lekkie dekoracje

22

To wyzwanie jest na cześć tandetnych lampek choinkowych w moim domu prawniczym.


Wyzwanie polega na stworzeniu graficznego wyniku przedstawiającego dekorację w „czasie rzeczywistym”.

Wideo (gif lub inny format) będzie miało pionowe i poziome „światła” n-by-m . 5 <= m, n <= 40 . Wielkość ramy i rozdzielczości może zmieniać się w zależności od n i m , jednak musi być co najmniej 50x50 pikseli o n M = 5 (grafiki wektorowe jest OK). Obraz z n=6i m=5będzie wyglądał mniej więcej tak:

wprowadź opis zdjęcia tutaj


Dekoracja:

Zabarwienie:

Wszystkie światła będzie mieć jedną z następujących 6 kolorów RGB {255,0,0}, {0,255,0}, {0,0,255}, {255,255,0}, {0,255,255}i {255,0,255}.

Animacja:

  • ni mbędą pobierane jako dane wejściowe w dowolnym rozsądnym formacie i w dowolnej kolejności
  • Obraz zmieni się co dt = 25 ms. Odchylenia są OK, jeśli wynika to z „czynników zewnętrznych”, takich jak ograniczenie tłumacza, powolny komputer itp.
    • Jeśli niemożliwe jest ręczne ustawienie kroku czasu, wówczas domyślny krok czasu jest akceptowany.
  • Wszystkie lampki będą świecić na czerwono ( {255,0,0}) o t=0.
  • Zawsze istnieje 5% szans, że pierwsze światło (u góry po lewej) zmieni kolor. Wszystkie kolory (oprócz koloru, który obecnie ma) powinny być jednakowo prawdopodobne.
  • Każde światło (oprócz pierwszego) otrzyma kolor światła po swojej lewej stronie. Jeśli światło znajduje się najdalej po lewej stronie, otrzyma kolor światła po prawej stronie w rzędzie powyżej. Światła są ponumerowane, jak pokazano poniżej. Jasna liczba kotrzyma kolor jasnej liczby k-1.

     1  2  3  4  5  6
     7  8  9 10 11 12
    13 14 15 16 17 18
    
  • Dane wyjściowe powinny teoretycznie działać wiecznie (chyba że Twój język / tłumacz ma jakieś ograniczenia, które temu zapobiegają).

  • Podaj próbkę o długości co najmniej 5 sekund, najlepiej więcej w odpowiedzi (jest to zachęta, a nie wymóg). (Link do TIO lub podobnego jest oczywiście OK: D)
  • Ramy, osie, linie siatki itp. Są akceptowane.

6 na 5

wprowadź opis zdjęcia tutaj

15 na 30

wprowadź opis zdjęcia tutaj

Stewie Griffin
źródło
Jeśli interpreter działa wolno, należy dostosować czas pauzy, aby całkowity czas między aktualizacjami obrazu był podobny jak w przykładach? Co jeśli pauza nie jest potrzebna (kod jest już wystarczająco powolny)? To zaoszczędzi bajty, być może wbrew duchowi wyzwania
Luis Mendo,
1
Skoro wybrałeś kolory w celu ułatwienia implementacji - w językach takich jak QBasic, które mają ograniczony wbudowany zestaw kolorów, czy dopuszczalne jest użycie najbliższych dostępnych kolorów do tych, które określiłeś? (Czerwony, zielony, niebieski, żółty, cyjan, magenta)
DLosc
Jeśli nie można użyć określonych kolorów, to tak, można użyć najbliższych alternatyw. Jeśli to tylko trochę dłużej, to nie. r,g,y,b,itp. są krótsze w kilku językach.
Stewie Griffin
@LuisMendo, przepraszamy za spóźnioną odpowiedź. Podoba mi się sposób, w jaki to zrobiłeś w swojej odpowiedzi. Można użyć 25 ms, nawet jeśli spowolni to animację. Unikałem, drawnowkiedy zaimplementowałem to w MATLAB, ponieważ wynik był zbyt wolny. Myślę, że odpowiedź musi być następująca: jeśli jest to wybór projektowy, że interpreter ma ustaloną minimalną rozdzielczość czasową> = 25 ms, to jest OK. Jeśli jest to spowodowane słabą / prostą implementacją, tłumaczem internetowym, który jest przeciążony / wolny itp., To nie jest OK.
Stewie Griffin,
1
@Stewie Rozumiem, dzięki. I miłe wyzwanie!
Luis Mendo,

Odpowiedzi:

6

JavaScript / CSS / HTML, 436 bajtów

b="red"
f=_=>{o.textContent='';o.style.width=w.value*10+"px";o.style.height=h.value*10+"px"}
setInterval(_=>o.insertBefore(document.createElement("s"),o.firstChild).style.background=b=["red","yellow","lime","aqua","blue","fuchsia"][Math.random()*100|0]||b,25)
#o{overflow:hidden;background:red}s{display:block;float:left;width:10px;height:10px}
<div oninput=f()><input id=h type=number min=1><input id=w type=number min=1></div><div id=o>

Neil
źródło
6

Mathematica, 186 161 158 bajtów

(b=Table[{1,0,0},1##];Dynamic@Image[Partition[[email protected];If[Random[]<.06,b[[1]]={1,1,0,0}~RandomSample~3];b=RotateRight@b;b[[1]]=b[[2]];b,#],ImageSize->50#])&

Wyjaśnienie

b=Table[{1,0,0},1##];

Utwórz początkową planszę w 1D, wypełnioną czerwonym. Przechowuj to w b.

[email protected]

Pauza na 25ms

If[Random[]<.06,b[[1]]={1,1,0,0}~RandomSample~3]

Jeśli (pseudo-) losowa liczba rzeczywista jest mniejsza niż 0,06, zastąp pierwszy element blosową długością próbki 3listy {1,1,0,0}. (tj. dowolny z {1, 1, 0}, {1, 0, 1}, {1, 0, 0}, {0, 1, 1}, {0, 1, 0}, {0, 0, 1})

b=RotateRight@b

Cykliczny obrót w prawo.

b[[1]]=b[[2]]

Zmień wartość pierwszej komórki na drugą wartość komórki (tj. Cofnij przesunięcie pierwszej komórki)

Partition[ ... ;b,#]

Podział bna (wysokość).

Dynamic@Image[ ... ,ImageSize->50#]

Zrób z tego dynamiczny (ciągle aktualizowany) obraz, którego szerokość wynosi 50 (szerokość)

Wersja automatu komórkowego (186 bajtów)

(b=Table[{1,0,0},1##];Dynamic@Image[Partition[[email protected];If[Random[]<.06,b[[1]]={1,1,0,0}~RandomSample~3];i=2;b={#[[2-Boole[i--<0],2]]&,{},{1,1}}~CellularAutomaton~b,#],ImageSize->50#])&

Przykładowe wyjście (wejścia: 16, 10)

wprowadź opis zdjęcia tutaj

JungHwan Min
źródło
6

MATLAB, 255 210 bajtów

To jest mój pierwszy golf, więc prawdopodobnie należy wprowadzić ulepszenia.

Dzięki Luisowi za pomoc w zaoszczędzeniu 45 bajtów :)

function f(n,m)
c=dec2bin(1:6)-48;r=1;p=c(r,:);x=zeros(1,n*m,3);x(:,:,1)=1;while 1
x=circshift(x,[0,1,0]);if rand>0.94;r=randi(6);end
x(1,1,:) = c(r,:);imagesc(permute(reshape(x,n,m,3),[2 1 3]));pause(1/40);end

Wyjaśnienie:

c=dec2bin(1:6)-48  % c is the colormap
r=1;p=c(r,:);                % p is color number r (starting at 1) from the colormap c
x=zeros(1,n*m,3);x(:,:,1)=1; % 2D matrix in the third dimension. The first layer is 1
while 1                      % while true
x=circshift(x,[0,1,0]);      % shift the vector horizontally along the second dimension
if rand()>0.94;              % 5 percent chance of changing color
k=randperm(6);k=k(k~=r);r=k(1); % Create a vector with color numbers 1..6. Discard the current color, and choose the first color
x(1,1,:) = c(r,:);           % The first light gets color number r
imagesc(permute(reshape(x,n,m,3),[2 1 3]));  % Reshape the vector so that it's a 3D matrix
% Permute it so that the dimensions are correct
% Use imagesc to display
pause(1/40)  % 0.025 seconds pause

Niestety nie zapisuje to animacji, po prostu ją uruchamia. Aby go zapisać, potrzebuję programu do przechwytywania ekranu lub przepisuję wszystko za pomocą imwrite. Zamiast tego dostarczę dwa zdjęcia przedstawiające różne czasy n=15,m=30.

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

CG
źródło
1
Kilka propozycji gry w golfa: dec2bin([4 2 1 6 3 5])-48zamiast [1 0 0;0 1 0;0 0 1;1 1 0; 0 1 1;1 0 1]. .95zamiast 0.95. Można również zastąpić .95przez .94i pozbyć się k=k(k~=r);(bo 0,06 + 0,94 / 6 = 0,95; patrz moja odpowiedź na bardziej szczegółowe wyjaśnienie)
Luis Mendo
1
Jeszcze lepiej c=dec2bin(1:6)-48, ponieważ kolejność nie ma znaczenia
Luis Mendo
Ładna pierwsza odpowiedź! Obawiam się jednak, że wygram z tobą o 40% .
Sanchises
Grałem trochę w golfa :) Dzięki za pomoc Luis. ! :) Dobra robota Sanchises!
CG.
4

MATL , 52 47 bajtów

6:BoHZGKipY"`tGe!2YG50Yr3>?t1)}6Yr]0(1YS.015Y.T

Dane wejściowe to tablica [ncols nrows]. Wyjście to postać z grafiką wektorową.

Przykładowy przebieg dla 15 kolumn × 10 wierszy:

wprowadź opis zdjęcia tutaj

Jak to działa

Czas pauzy został ustawiony na 15 ms (dla tej samej liczby bajtów co 25 ms), aby spróbować zrekompensować czas przetwarzania.

Aby zachować kolor z prawdopodobieństwem 19/20 (zmień go na 1/20), postępujemy w następujący sposób:

  • Z prawdopodobieństwem 47/50 zachowujemy kolor.
  • Z prawdopodobieństwem 3/50 wybieramy nowy kolor wybrany równomiernie spośród 6 kolorów. Może się zdarzyć, że „nowy” kolor jest taki sam jak stary, i dzieje się tak z prawdopodobieństwem 1/6.

Zatem prawdopodobieństwo utrzymania koloru wynosi 47/50 + 3 / (50 * 6) = 19/20.

6:        % Push [1 2 3 4 5 6]
B         % Convert to binary. This gives a 6×3 matrix, where each row 
          % corresponds to a number. First row is [0 0 1] (blue), second is
          % [0 1 0] (green), etc
o         % Convert to double
HZG       % Set as colormap (creates a figure)
K         % Push 4
i         % Take input array
p         % Product of array. This gives the total number of squares
Y"        % Repeat 4 that many times. This gives a row vector representing the
          % image. The initial value, 4, corresponds to red in the colormap
`         % Do...while
  t       %   Duplicate
  Ge      %   Reshape to size given by the input. Gives a matrix where each
          %   entry  will be interpreted as a pointer to the colormap
  !       %   Transpose. This is required because the color shifting will be
          %   done in column-major order: down, then across; whereas we want
          %   the opposite
  2YG     %   Show matrix as image using the defined colormap
  50Yr    %   Push a uniformly distributed random integer between 1 and 50
  3>      %   True if greater than 3. This happens with probability 47/50
  ?       %   If true
    t1)   %     Duplicate and get first entry (to repeat the first color)
  }       %   Else
    6Yr   %     Push a uniformly distributed random integer between 1 and 6.
          %     This is the new color (possibly the same as the old)
  ]       %   End
  0(      %   Assign that color (repeated or new) to the last entry of the row
          %   vector representing the image
  1YS     %   Circularly shift to the right. The last value becomes the first
 .015Y.   %   Pause 0.015 ms
 T        %   Push true
          % End (implicit). Since the top of the stack is true, this creates
          % an infinite loop
Luis Mendo
źródło
3

MATLAB, 153 147 bajtów

Uwaga : Pokazany GIF jest starszej wersji, co jest miłe, ponieważ nie wyświetla osi (patrz historia edycji), ale było bardzo wolne ze względu na implementację imshow. W obecnej wersji odpowiedź MATLAB Chelsea G. lub odpowiedź MATL Luisa Mendo pokazują ten sam wynik, co moja obecna wersja.

Rozmiar jest traktowany jako 2x1wektor, więc nazywamy go np .:

>> l([5 5])

function l(s)
c=eye(3);x=eye(s);while 1
a=rand>.94;x=[a*randi(6)+~a*x(1),x(1:end-1)];imagesc(reshape(x,s)',[1,6]);colormap([c;1-c])
pause(.025)
end

Ta odpowiedź wykorzystuje subtelności języka MATLAB. Na przykład xjest inicjowany jako m x nmacierz zerowa, ale tak zwane indeksowanie liniowe pozwala na przesunięcie kołowe za pomocą wskaźników 1-wymiarowych. Słabe pisanie pozwala na mnożenie za pomocą logiki, dzięki czemu ifunika się instrukcji (sztuczka, którą często stosowałem w czasach programowania na kalkulatorze TI-84). Mimo że mapa kolorów jest odczytywana wierszowo, MATLAB traktuje ją jak normalną matrycę, dzięki czemu eye(3)można jej użyć do tworzenia czerwieni, zieleni i niebieskiego oraz 1-eye(3)pozostałych trzech kolorów. Prosty reshapesprowadza wektor liniowy z powrotem do postaci matrycy, która jest odwzorowywana za pomocą pożądanych kolorówind2rgb . Wreszcie,imagesc, pokazuje obraz pokazany przy domyślnym rozmiarze figury (który jest wystarczająco duży dla wymagań). Życie to jest to, imagescnie przeszkadza wartości są poza określony zakres, więc eyemoże być używany do inicjalizacji macierzy ponieważ oba 1i 0są uważane czerwono.

wprowadź opis zdjęcia tutaj

Sanchises
źródło
1
Ups, zapomniałem cię głosować ... Uwielbiam wszystkie twoje małe sztuczki :-)
CG.
Czy to prawda, że ​​losowy kolor nigdy nie jest czerwony w zaktualizowanej wersji? Tak przynajmniej wygląda w Octave (nie posiadaj MATLAB).
Stewie Griffin
@StewieGriffin Musiałem spać, kiedy to zrobiłem. Masz oczywiście całkowitą rację - i to także uratowało mi bajt ...
Sanchises
(zrób te dwa bajty)
Sanchises
2

Python 3.6 (316 bajtów)

Używanie kodów kolorów ANSI i nowych sformatowanych literałów łańcuchowych w Pythonie 3.6 ( PEP 489 ) (f"{X}" magia).

W przeciwnym razie jest to po prostu dość prosty, ale zaciemniony python. Szerokość i wysokość są przekazywane jako argumenty w wierszu poleceń.

import random as n,time,sys
r=range
X="\x1b["
C=[f"{X}1;4{x}m " for x in r(1,7)]
w,h=list(map(int,sys.argv[1:]))
a=[C[0]for i in r(w*h)]
while 1:
 print(f"{X}0m{X}2J{X}f");f=a[0];a.pop();a[:0]=n.choice([x for x in C if x!=f])if n.random()<=.05 else f,
 for i in r(0,h*w,w):print(*a[i:i+w],sep="")
 time.sleep(.025)

wprowadź opis zdjęcia tutaj

Jonas Schäfer
źródło
Możesz zaoszczędzić 6 bajtów przy użyciu w,h=map(int,sys.argv[1:]), rozpakowanie działa z dowolnym iterowalnym (odpowiedniego rozmiaru), wywołanie listy jest zbędne.
Sebastian Riese,
Kolejne kilka bajtów w dół: "\x1b["=> "\33["(używając znaków ósemkowych zamiast znaków szesnastkowych), a następnie skrót X i ciągi formatujące faktycznie f""wydłużają go (i pozbywając się , uzyskujesz zgodność z dowolnym python3). (obniży to do 301 bajtów).
Sebastian Riese,
Ups, używasz {x}raz ... ale wciąż wygrywasz z pozbyciem się X.
Sebastian Riese,