Animare decorazioni luminose appiccicose


22

Questa sfida è in onore delle luci di Natale appiccicose nella casa dei miei suoceri.


La sfida è creare un output grafico che mostri la decorazione in "tempo reale".

Il video (GIF o altro formato) avrà "luci" verticali e orizzontali n-by-m . 5 <= m, n <= 40 . La dimensione di frame e la risoluzione possono variare a seconda n ed m , ma devono essere almeno 50x50 pixel per n, m = 5 (vettore grafica è OK). Una foto con n=6e m=5sarà simile a questa:

inserisci qui la descrizione dell'immagine


La decorazione:

Colori:

Tutte le luci avranno una delle seguenti 6 RGB-colori {255,0,0}, {0,255,0}, {0,0,255}, {255,255,0}, {0,255,255}e {255,0,255}.

Animazione:

  • ne mverrà preso come input in qualsiasi formato ragionevole e nell'ordine che ti piace
  • L'immagine cambierà ogni dt = 25 ms. Le deviazioni vanno bene se sono dovute a "fattori esterni" come limitazione nell'interprete, computer lento ecc.
    • Se è impossibile impostare manualmente la fase temporale, viene accettata la fase temporale predefinita.
  • Tutte le luci saranno rosse ( {255,0,0}) a t=0.
  • C'è sempre una probabilità del 5% che la prima luce (in alto a sinistra) cambierà colore. Tutti i colori (tranne il colore che ha attualmente) dovrebbero essere ugualmente probabili.
  • Ogni luce (tranne la prima) otterrà il colore della luce alla sua sinistra. Se la luce è all'estrema sinistra, otterrà il colore della luce all'estrema destra sulla riga sopra. Le luci sono numerate come mostrato di seguito. Il numero di luce kotterrà il colore del numero di luce k-1.

     1  2  3  4  5  6
     7  8  9 10 11 12
    13 14 15 16 17 18
    
  • L'output dovrebbe in teoria funzionare per sempre (a meno che il tuo linguaggio / interprete non abbia alcune limitazioni che lo impediscono).

  • Fornisci un campione di almeno 5 secondi, preferibilmente più nella risposta (questo è un incoraggiamento, non un requisito). (Ovviamente anche un collegamento a TIO o simili è OK: D)
  • Sono accettati cornici, assi, linee di griglia ecc.

6-by-5

inserisci qui la descrizione dell'immagine

15-by-30

inserisci qui la descrizione dell'immagine


Se l'interprete è lento, dovrebbe essere necessario regolare il tempo di pausa in modo che il tempo totale tra gli aggiornamenti delle immagini sia simile a quello degli esempi? Che dire se la pausa non è necessaria (il codice è già abbastanza lento)? Ciò consentirebbe di risparmiare byte, forse contro lo spirito della sfida
Luis Mendo il

1
Dato che hai scelto i colori per semplificare l'implementazione - in linguaggi come QBasic che hanno un set di colori incorporato limitato, è accettabile utilizzare i colori disponibili più vicini a quelli che hai specificato? (Rosso, verde, blu, giallo, ciano, magenta)
DLosc

Se è impossibile utilizzare i colori specificati, sì, è possibile utilizzare le alternative più vicine. Se è solo un po 'più lungo, allora no. r,g,y,b,ecc. sono più brevi in ​​diverse lingue.
Stewie Griffin,

@LuisMendo, mi scuso per la risposta tardiva. Mi piace il modo in cui l'hai fatto nella tua risposta. Sarebbe OK usare 25 ms, anche se ciò rallenterebbe l'animazione. L'ho evitato drawnowquando l'ho implementato in MATLAB, poiché il risultato è stato troppo lento. Penso che la risposta debba essere: se è una scelta progettuale che l'interprete abbia una risoluzione temporale minima fissa> = 25 ms, allora va bene. Se è dovuto a un'implementazione scarsa / semplice, un interprete online sovraccarico / lento ecc., Allora non va bene.
Stewie Griffin,

1
@Stewie Capito, grazie. E bella sfida!
Luis Mendo,

Risposte:


6

JavaScript / CSS / HTML, 436 byte

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>


6

Mathematica, 186 161 158 byte

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

Spiegazione

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

Crea la scheda iniziale in 1D, riempita di rosso. Conservalo in b.

Pause@.025

Pausa per 25 ms

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

Se un numero reale (pseudo-) casuale è inferiore a 0,06, sostituire il primo elemento di bcon una lunghezza campione casuale 3dell'elenco {1,1,0,0}. (ovvero uno qualsiasi di {1, 1, 0}, {1, 0, 1}, {1, 0, 0}, {0, 1, 1}, {0, 1, 0}, {0, 0, 1})

b=RotateRight@b

Ciclico ruota a destra.

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

Modifica il valore della prima cella sul valore della seconda cella (ovvero annulla lo spostamento della prima cella)

Partition[ ... ;b,#]

Partizione bin (altezza).

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

Trasformalo in un'immagine dinamica (in costante aggiornamento), la cui larghezza è 50 (larghezza)

Versione automa cellulare (186 byte)

(b=Table[{1,0,0},1##];Dynamic@Image[Partition[Pause@.025;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#])&

Uscita campione (ingressi: 16, 10)

inserisci qui la descrizione dell'immagine


6

MATLAB, 255 210 byte

Questo è il mio primo golf, quindi probabilmente ci sono miglioramenti da apportare.

Grazie a Luis per avermi aiutato a salvare 45 byte :)

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

Spiegazione:

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

Sfortunatamente, questo non salva l'animazione, ma la esegue. Per salvarlo ho bisogno di un programma di cattura dello schermo o riscrivo tutto usando imwrite. Invece, fornirò due immagini che mostrano tempi diversi, per n=15,m=30.

inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


1
Alcuni suggerimenti sul golf: dec2bin([4 2 1 6 3 5])-48invece di [1 0 0;0 1 0;0 0 1;1 1 0; 0 1 1;1 0 1]. .95invece di 0.95. È inoltre possibile sostituire .95da .94e sbarazzarsi di k=k(k~=r);(perché 0.94 + 0.06 / 6 = 0,95; vedi la mia risposta per una spiegazione più dettagliata)
Luis Mendo

1
Meglio ancora, c=dec2bin(1:6)-48poiché l'ordine non ha importanza
Luis Mendo il

Bella prima risposta! Tuttavia, temo di averti superato del 40% .
Sanchises,

Scivolò un po ':) Grazie per l'aiuto Luis. ! :) Ben fatto Sanchises!
CG.

4

MATL , 52 47 byte

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

L'input è un array [ncols nrows]. L'output è una figura con grafica vettoriale.

Esempio di esecuzione per 15 colonne × 10 righe:

inserisci qui la descrizione dell'immagine

Come funziona

Il tempo di pausa è stato impostato su 15 ms (per lo stesso conteggio dei byte di 25 ms) per provare a compensare il tempo di elaborazione.

Per mantenere il colore con probabilità 19/20 (cambiarlo con 1/20), procediamo come segue:

  • Con una probabilità 47/50 manteniamo il colore.
  • Con 3/50 di probabilità scegliamo un nuovo colore scelto uniformemente tra i 6 colori. Può succedere che il "nuovo" colore sia uguale al vecchio e ciò si verifica con probabilità 1/6.

Quindi la probabilità di mantenere il colore è 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

3

MATLAB, 153 147 byte

Nota : la GIF mostrata è della versione precedente, che è carina in quanto non mostra gli assi (vedi cronologia delle modifiche), ma è stata estremamente lenta a causa dell'implementazione di imshow. Per la versione attuale, la risposta MATLAB di Chelsea G. o la risposta MATL di Luis Mendo mostrano lo stesso risultato della mia versione attuale.

Le dimensioni sono prese come un 2x1vettore, quindi chiama come ad esempio:

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

Questa risposta sfrutta le sottigliezze del linguaggio MATLAB. Ad esempio, xè initalizzato come m x nmatrice zero, ma il cosiddetto indicizzazione lineare consente lo spostamento circolare con indici monodimensionali. La digitazione debole consente la moltiplicazione con i logici, in modo da ifevitare le dichiarazioni (un trucco che ho usato pesantemente nei giorni di programmazione su un calcolatore TI-84). Anche se una mappa dei colori viene letta per riga, MATLAB la tratta come una matrice normale, in modo che eye(3)possa essere utilizzata per creare rosso, verde e blu e 1-eye(3)gli altri tre colori. Un semplice reshaperiporta il vettore lineare in forma matrice, che viene mappato sui colori desiderati usando ind2rgb. Finalmente,imagesc, mostra l'immagine, mostrata con le dimensioni predefinite (che è abbastanza grande per i requisiti). Per fortuna, imagescnon importa se i valori sono al di fuori dell'intervallo specificato, quindi eyepossono essere utilizzati per inizializzare la matrice poiché entrambi 1e 0sono considerati rossi.

inserisci qui la descrizione dell'immagine


1
Oops, ho dimenticato di votarti ... Adoro tutti i tuoi piccoli trucchi :-)
CG.

È corretto che il colore casuale non sia mai rosso nella versione aggiornata? Sembra almeno così in Octave (non hai MATLAB).
Stewie Griffin,

@StewieGriffin Devo aver dormito quando l'ho fatto. Naturalmente hai perfettamente ragione - e mi ha anche salvato un byte ...
Sanchises il

(crea due byte)
Sanchises il

2

Python 3.6 (316 byte)

Utilizzo dei codici colore ANSI e dei nuovi letterali stringa formattati di Python 3.6 ( PEP 489 ) (la f"{X}"magia).

Altrimenti è un pitone piuttosto semplice, ma offuscato. Larghezza e altezza vengono passati come argomenti sulla riga di comando.

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)

inserisci qui la descrizione dell'immagine


Puoi risparmiare 6 byte usando w,h=map(int,sys.argv[1:]), decomprimendo le opere con qualsiasi iterabile (della giusta dimensione), la chiamata all'elenco è superflua.
Sebastian Riese,

Un altro paio di byte in basso: "\x1b["=> "\33["(usando ottale invece di escape esadecimali), quindi l'abbreviazione X e le stringhe di formato la rendono effettivamente più lunga (e sbarazzandosi di f""te si ottiene la compatibilità con qualsiasi python3). (questo lo porterà a 301 byte).
Sebastian Riese,

Oops, lo usi {x}una volta ... ma vinci ancora con il sbarazzartene X.
Sebastian Riese,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.