Animieren Sie klebrige Lichtdekorationen

22

Diese Herausforderung ist zu Ehren der klebrigen Weihnachtsbeleuchtung in meinem Haus.


Die Herausforderung besteht darin, eine grafische Ausgabe zu erstellen, die die Dekoration in "Echtzeit" zeigt.

Das Video (GIF oder ein anderes Format) hat n-mal-m vertikale und horizontale "Lichter". 5 <= m, n <= 40 . Die Bildgröße und Auflösung können in Abhängigkeit von n und m variieren , müssen jedoch mindestens 50 x 50 Pixel für n, m = 5 betragen (Vektorgrafiken sind in Ordnung). Ein Bild mit n=6und m=5sieht ungefähr so ​​aus:

Bildbeschreibung hier eingeben


Die Verzierung:

Farben:

Alle Leuchten haben eine der folgenden 6 RGB-Farben {255,0,0}, {0,255,0}, {0,0,255}, {255,255,0}, {0,255,255}und {255,0,255}.

Animation:

  • nund mwerden als Eingabe für jedes vernünftige Format und in der von Ihnen gewünschten Reihenfolge verwendet
  • Das Bild ändert sich bei jedem dt = 25 ms. Abweichungen sind in Ordnung, wenn sie auf "äußere Faktoren" zurückzuführen sind, z. B. Einschränkungen im Interpreter, langsame Computer usw.
    • Wenn es nicht möglich ist , den Zeitschritt manuell einzustellen, wird der Standardzeitschritt akzeptiert.
  • Alle Lichter leuchten rot ( {255,0,0}) bei t=0.
  • Es besteht immer eine Wahrscheinlichkeit von 5%, dass das erste Licht (oben links) die Farbe ändert. Alle Farben (mit Ausnahme der aktuellen Farbe) sollten gleich wahrscheinlich sein.
  • Jedes Licht (außer dem ersten) erhält die Farbe des Lichts auf der linken Seite. Befindet sich das Licht ganz links, erhält es die Farbe des Lichts ganz rechts in der Zeile darüber. Die Lichter sind wie unten gezeigt nummeriert. Lichtnummer kerhält die Farbe der Lichtnummer k-1.

     1  2  3  4  5  6
     7  8  9 10 11 12
    13 14 15 16 17 18
    
  • Die Ausgabe sollte theoretisch für immer laufen (es sei denn, Ihre Sprache / Ihr Interpreter hat eine Einschränkung, die dies verhindert).

  • Bitte geben Sie eine Probe von mindestens 5 Sekunden an, vorzugsweise mehr in der Antwort (dies ist eine Ermutigung, keine Voraussetzung). (Ein Link zu TIO oder ähnlichem ist natürlich auch in Ordnung: D)
  • Rahmen, Achsen, Gitterlinien usw. werden akzeptiert.

6-mal-5

Bildbeschreibung hier eingeben

15-mal-30

Bildbeschreibung hier eingeben

Stewie Griffin
quelle
Wenn der Interpreter langsam ist, sollte die Pausenzeit so angepasst werden, dass die Gesamtzeit zwischen den Bildaktualisierungen der in den Beispielen entspricht. Was ist, wenn die Pause nicht benötigt wird (der Code ist bereits langsam genug)? Das würde Bytes sparen, vielleicht gegen den Geist der Herausforderung
Luis Mendo
1
Da Sie die Farben zur Vereinfachung der Implementierung ausgewählt haben - in Sprachen wie QBasic mit einer begrenzten Anzahl von Farben - ist es akzeptabel, die Farben zu verwenden, die den von Ihnen angegebenen Farben am nächsten kommen? (Rot, Grün, Blau, Gelb, Cyan, Magenta)
DLosc
Wenn es nicht möglich ist, die angegebenen Farben zu verwenden, ist es in Ordnung, die nächstgelegenen Alternativen zu verwenden. Wenn es nur ein bisschen länger ist, dann nein. r,g,y,b,usw. sind in mehreren Sprachen kürzer.
Stewie Griffin
@ LuisMendo, entschuldige mich für die verspätete Antwort. Ich finde es gut, wie du es in deiner Antwort getan hast. Es wäre in Ordnung, 25 ms zu verwenden, selbst wenn dies die Animation verlangsamen würde. Ich habe es vermieden, drawnowals ich dies in MATLAB implementiert habe, da das Ergebnis zu langsam war. Ich denke, die Antwort muss lauten: Wenn es sich um eine Entwurfsentscheidung handelt, bei der der Interpreter eine feste Mindestzeitauflösung von> = 25 ms hat, ist dies in Ordnung. Wenn dies auf eine schlechte / einfache Implementierung, einen überlasteten / langsamen Online-Interpreter usw. zurückzuführen ist, ist dies nicht in Ordnung.
Stewie Griffin
1
@Stewie Verstanden, danke. Und schöne Herausforderung!
Luis Mendo

Antworten:

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>

Neil
quelle
6

Mathematica, 186 161 158 Bytes

(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#])&

Erläuterung

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

Erstellen Sie die erste Tafel in 1D, gefüllt mit Rot. Bewahren Sie das in b.

[email protected]

Pause für 25ms

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

Wenn eine (pseudo-) zufällige reelle Zahl kleiner als 0,06 ist, ersetzen Sie das erste Element von bdurch eine zufällige Stichprobenlänge 3der Liste {1,1,0,0}. (dh eines von {1, 1, 0}, {1, 0, 1}, {1, 0, 0}, {0, 1, 1}, {0, 1, 0}, {0, 0, 1})

b=RotateRight@b

Zyklisch nach rechts drehen.

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

Ändern Sie den ersten Zellenwert in den zweiten Zellenwert (dh machen Sie die Verschiebung der ersten Zelle rückgängig)

Partition[ ... ;b,#]

Einteilung bin (Höhe).

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

Machen Sie daraus ein dynamisches (ständig aktualisierendes) Bild, dessen Breite 50 (Breite) beträgt.

Mobilfunkversion (186 Bytes)

(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#])&

Beispielausgabe (Eingänge: 16, 10)

Bildbeschreibung hier eingeben

JungHwan min
quelle
6

MATLAB, 255 210 Bytes

Dies ist mein erstes Golfspiel, daher müssen wahrscheinlich Verbesserungen vorgenommen werden.

Danke an Luis, der mir geholfen hat, 45 Bytes zu sparen :)

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

Erläuterung:

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

Leider wird die Animation dadurch nicht gespeichert, sondern nur ausgeführt. Um es zu speichern, benötige ich entweder ein Screen-Capture-Programm oder schreibe alles mit imwrite. Stattdessen stelle ich zwei Bilder zur Verfügung, die unterschiedliche Zeiten zeigen, z n=15,m=30.

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

CG.
quelle
1
Einige Golfvorschläge: dec2bin([4 2 1 6 3 5])-48statt [1 0 0;0 1 0;0 0 1;1 1 0; 0 1 1;1 0 1]. .95statt 0.95. Sie können auch ersetzen .95durch .94und loszuwerden k=k(k~=r);(weil 0,94 + 0,06 / 6 = 0,95; meine Antwort für eine ausführlichere Erklärung sehen)
Luis Mendo
1
Besser noch, c=dec2bin(1:6)-48da die Reihenfolge keine Rolle spielt
Luis Mendo
Schöne erste Antwort! Ich fürchte jedoch, ich habe Sie um 40% übertroffen .
Sanchises
Golf es ein bisschen runter :) Danke für die Hilfe Luis. ! :) Gut gemacht Sanchises!
CG.
4

MATL , 52 47 Bytes

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

Die Eingabe ist ein Array [ncols nrows]. Ausgabe ist eine Zahl mit Vektorgrafiken.

Beispiellauf für 15 Spalten × 10 Reihen:

Bildbeschreibung hier eingeben

Wie es funktioniert

Die Pausenzeit wurde auf 15 ms eingestellt (für die gleiche Bytezahl wie 25 ms), um die Verarbeitungszeit auszugleichen.

Um die Farbe mit 19/20 Wahrscheinlichkeit zu behalten (mit 1/20 zu ändern), gehen wir wie folgt vor:

  • Mit 47/50 Wahrscheinlichkeit behalten wir die Farbe.
  • Mit einer Wahrscheinlichkeit von 3/50 wählen wir eine neue Farbe aus, die einheitlich aus den 6 Farben ausgewählt wird. Es kann vorkommen, dass die "neue" Farbe dieselbe ist wie die alte, und dies geschieht mit einer Wahrscheinlichkeit von 1/6.

Somit beträgt die Wahrscheinlichkeit, die Farbe zu behalten, 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
quelle
3

MATLAB, 153 147 Bytes

Hinweis : Das gezeigte GIF ist von der älteren Version, was nett ist, da es keine Achsen anzeigt (siehe Bearbeitungsverlauf), aber aufgrund der Implementierung von extrem langsam war imshow. Für die aktuelle Version zeigen die MATLAB-Antwort von Chelsea G. oder die MATL-Antwort von Luis Mendo dasselbe Ergebnis wie meine aktuelle Version.

Die Größe wird als 2x1Vektor verwendet, nennen Sie also zB:

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

Diese Antwort nutzt die Feinheiten der MATLAB-Sprache aus. Beispielsweise xwird als m x nNullmatrix initialisiert , die sogenannte lineare Indizierung ermöglicht jedoch eine zirkuläre Verschiebung mit eindimensionalen Indizes. Eine schwache Eingabe ermöglicht die Multiplikation mit logischen Werten, sodass ifAussagen vermieden werden (ein Trick, den ich in den Tagen der Programmierung auf einem TI-84-Rechner häufig angewendet habe). Auch wenn eine Farbkarte zeilenweise gelesen wird, wird sie in MATLAB als normale Matrix behandelt, sodass eye(3)Rot, Grün und Blau sowie 1-eye(3)die anderen drei Farben erstellt werden können. Ein einfaches reshapebringt den linearen Vektor zurück in die Matrixform, die mit den gewünschten Farben abgebildet wird ind2rgb. Endlich,imagesc, zeigt das Bild in der Standardgröße (die für die Anforderungen groß genug ist). Wie es der Zufall wollte, imagesckeine Werte dagegen außerhalb des angegebenen Bereichs zu sein, so eyekann die Matrix , da beide zu initialisieren 1und 0werden rot betrachtet.

Bildbeschreibung hier eingeben

Sanchises
quelle
1
Ups, ich habe vergessen dich zu verbessern ... Ich liebe all deine kleinen Tricks :-)
CG.
Ist es richtig, dass die zufällige Farbe in der aktualisierten Version niemals rot ist? Zumindest in Octave sieht es so aus (habe kein MATLAB).
Stewie Griffin
@StewieGriffin Ich muss geschlafen haben, als ich das gemacht habe. Sie haben natürlich vollkommen recht - und es hat mir auch ein Byte
erspart
(machen Sie diese zwei Bytes)
Sanchises
2

Python 3.6 (316 Bytes)

Verwenden von ANSI-Farbcodes und den neu formatierten Zeichenfolgenliteralen von Python 3.6 ( PEP 489 ) (the f"{X}"magic).

Ansonsten ist es nur ziemlich einfaches, aber verschleiertes Python. Breite und Höhe werden in der Befehlszeile als Argumente übergeben.

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)

Bildbeschreibung hier eingeben

Jonas Schäfer
quelle
Sie können 6 Bytes sparen, indem Sie verwenden w,h=map(int,sys.argv[1:]), das Entpacken funktioniert mit jedem iterablen (der richtigen Größe), der Aufruf der Liste ist überflüssig.
Sebastian Riese
Noch ein paar Bytes nach unten: "\x1b["=> "\33["(Verwenden von Oktal anstelle von Hex- f""Escape-Zeichen) , dann wird es durch die X-Abkürzung und die Format-Zeichenfolgen tatsächlich länger (und wenn Sie es loswerden, erhalten Sie Kompatibilität mit jedem Python3). (Dadurch wird es auf 301 Bytes reduziert).
Sebastian Riese
Ups, du verwendest es {x}einmal ... aber du gewinnst immer noch damit, es loszuwerden X.
Sebastian Riese