Menghidupkan dekorasi cahaya norak

22

Tantangan ini untuk menghormati lampu Natal yang norak di rumah mertua saya.


Tantangannya adalah membuat keluaran grafis yang menunjukkan dekorasi dalam "waktu nyata".

Video (gif atau format lain) akan memiliki "lampu" vertikal dan horizontal n-by-m . 5 <= m, n <= 40 . Ukuran dan resolusi bingkai dapat bervariasi tergantung pada n dan m , tetapi harus setidaknya 50x50 piksel untuk n, m = 5 (grafik vektor OK). Gambar dengan n=6dan m=5akan terlihat seperti ini:

masukkan deskripsi gambar di sini


Dekorasi:

Warna:

Semua lampu akan memiliki salah satu dari berikut 6 RGB-warna {255,0,0}, {0,255,0}, {0,0,255}, {255,255,0}, {0,255,255}dan {255,0,255}.

Animasi:

  • ndan makan diambil sebagai input pada format apa pun yang masuk akal dan dalam urutan yang Anda suka
  • Gambar akan berubah setiap dt = 25 ms. Penyimpangan baik-baik saja jika itu karena "faktor luar" seperti keterbatasan dalam penerjemah, komputer lambat dll.
    • Jika tidak mungkin untuk mengatur langkah waktu secara manual, maka langkah waktu default diterima.
  • Semua lampu akan berwarna merah ( {255,0,0}) pada t=0.
  • Selalu ada peluang 5% bahwa cahaya pertama (kiri atas) akan berubah warna. Semua warna (kecuali warna yang dimilikinya saat ini) harus memiliki kemungkinan yang sama.
  • Setiap cahaya (kecuali yang pertama) akan mendapatkan warna cahaya ke kiri. Jika cahaya berada di paling kiri maka akan mendapatkan warna cahaya di paling kanan pada baris di atas. Lampu diberi nomor seperti yang ditunjukkan di bawah ini. Nomor cahaya kakan mendapatkan warna nomor cahaya k-1.

     1  2  3  4  5  6
     7  8  9 10 11 12
    13 14 15 16 17 18
    
  • Keluaran harus secara teori dijalankan selamanya (kecuali bahasa / penerjemah Anda memiliki batasan yang mencegah hal ini).

  • Harap berikan sampel minimal 5 detik, lebih disukai dalam jawabannya (ini adalah dorongan, bukan persyaratan). (Tautan ke TIO atau yang serupa tentu saja juga OK: D)
  • Frame, sumbu, garis kisi, dll diterima.

6-oleh-5

masukkan deskripsi gambar di sini

15-kali-30

masukkan deskripsi gambar di sini

Stewie Griffin
sumber
Jika penerjemahnya lambat, harus menyesuaikan waktu jeda sehingga total waktu antara pembaruan gambar mirip dengan yang ada dalam contoh? Bagaimana jika jeda tidak diperlukan (kode sudah cukup lambat)? Itu akan menghemat byte, mungkin melawan semangat tantangan
Luis Mendo
1
Karena Anda memilih warna untuk kemudahan implementasi - dalam bahasa seperti QBasic yang memiliki rangkaian warna terbatas, dapatkah menggunakan warna terdekat yang tersedia dengan yang Anda tentukan? (Merah, hijau, biru, kuning, cyan, magenta)
DLosc
Jika tidak mungkin untuk menggunakan warna yang ditentukan maka ya, tidak apa-apa untuk menggunakan alternatif terdekat. Jika hanya sedikit lebih lama maka tidak. r,g,y,b,dll lebih pendek dalam beberapa bahasa.
Stewie Griffin
@LuisMendo, permintaan maaf atas jawaban yang terlambat. Saya suka cara Anda melakukannya dalam jawaban Anda. Tidak apa-apa untuk menggunakan 25 ms, bahkan jika itu akan membuat animasi lebih lambat. Saya menghindari drawnowketika saya menerapkan ini di MATLAB, karena hasilnya terlalu lambat. Saya pikir jawabannya harus: Jika itu adalah pilihan desain bahwa penerjemah memiliki resolusi waktu minimum tetap> = 25 ms maka tidak apa-apa. Jika itu karena implementasi yang buruk / sederhana, penerjemah online yang kelebihan beban / lambat dll. Maka itu tidak OK.
Stewie Griffin
1
@Stewie mengerti, terima kasih. Dan tantangan yang bagus!
Luis Mendo

Jawaban:

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

Penjelasan

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

Buat papan awal dalam 1D, diisi dengan warna merah. Simpan itu dib .

[email protected]

Jeda selama 25 ms

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

Jika bilangan real acak (pseudo-) kurang dari 0,06, ganti elemen pertama bdengan panjang sampel acak 3dari daftar {1,1,0,0}. (Yaitu salah satu dari{1, 1, 0}, {1, 0, 1}, {1, 0, 0}, {0, 1, 1}, {0, 1, 0}, {0, 0, 1} )

b=RotateRight@b

Putar siklik ke kanan.

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

Ubah nilai sel pertama ke nilai sel kedua (yaitu membatalkan pergeseran sel pertama)

Partition[ ... ;b,#]

Partisi bmenjadi (tinggi).

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

Jadikan itu menjadi gambar dinamis (terus-menerus memperbarui), yang lebarnya 50 (lebar)

Versi otomat seluler (186 byte)

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

Contoh Output (input: 16, 10)

masukkan deskripsi gambar di sini

JungHwan Min
sumber
6

MATLAB, 255 210 byte

Ini golf pertama saya, jadi mungkin ada perbaikan yang harus dilakukan.

Terima kasih kepada Luis karena membantu saya menghemat 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

Penjelasan:

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

Sayangnya, ini tidak menyimpan animasi, itu hanya menjalankannya. Untuk menyimpannya, saya memerlukan program tangkapan layar, atau menulis ulang semuanya menggunakan imwrite. Sebagai gantinya, saya akan memberikan dua gambar yang menunjukkan waktu yang berbeda, untuk n=15,m=30.

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

CG.
sumber
1
Beberapa saran bermain golf: dec2bin([4 2 1 6 3 5])-48alih-alih [1 0 0;0 1 0;0 0 1;1 1 0; 0 1 1;1 0 1]. .95bukannya 0.95. Anda juga dapat menggantinya .95dengan .94dan menyingkirkan k=k(k~=r);(karena 0,94 + 0,06 / 6 = 0,95; lihat jawaban saya untuk penjelasan yang lebih terperinci)
Luis Mendo
1
Lebih baik lagi, c=dec2bin(1:6)-48karena pesanan tidak penting
Luis Mendo
Jawaban pertama yang bagus! Namun, saya khawatir saya telah mengalahkan Anda sebesar 40% .
Sanchises
Golf turun sedikit :) Terima kasih atas bantuannya Luis. ! :) Sanchises dilakukan dengan baik!
CG.
4

MATL , 52 47 byte

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

Input adalah sebuah array [ncols nrows] . Output adalah gambar dengan grafik vektor.

Contoh dijalankan selama 15 cols × 10 baris:

masukkan deskripsi gambar di sini

Bagaimana itu bekerja

Jeda waktu telah diatur ke 15 ms (untuk jumlah byte yang sama dengan 25 ms) untuk mencoba mengkompensasi waktu pemrosesan.

Untuk mempertahankan warna dengan probabilitas 19/20 (ubah dengan 1/20), kami melanjutkan sebagai berikut:

  • Dengan probabilitas 47/50 kami mempertahankan warnanya.
  • Dengan probabilitas 3/50 kami memilih warna baru yang dipilih secara seragam di antara 6 warna. Bisa terjadi bahwa warna "baru" sama dengan yang lama, dan ini terjadi dengan probabilitas 1/6.

Dengan demikian probabilitas menjaga warna adalah 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
sumber
3

MATLAB, 153 147 byte

Catatan : GIF yang ditampilkan adalah versi yang lebih lama, yang bagus karena tidak menampilkan sumbu (lihat riwayat edit), tetapi sangat lambat karena implementasi imshow. Untuk versi saat ini, jawaban MATLAB Chelsea G. atau jawaban Luis Mendo MATL menunjukkan hasil yang sama dengan versi saya saat ini.

Ukuran diambil sebagai 2x1vektor, jadi panggil misalnya:

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

Jawaban ini mengeksploitasi seluk-beluk bahasa MATLAB. Sebagai contoh, xdiinisialisasi sebagai m x nmatriks nol, tetapi yang disebut pengindeksan linear memungkinkan untuk pergeseran melingkar dengan indeks 1-dimensi. Lemah mengetik memungkinkan untuk perkalian dengan logika, sehingga ifpernyataan dihindari (trik saya banyak digunakan kembali pada masa pemrograman dengan kalkulator TI-84). Meskipun colormap dibaca dengan menggunakan baris, MATLAB memperlakukannya sebagai matriks normal, sehingga eye(3)dapat digunakan untuk membuat merah, hijau dan biru, dan 1-eye(3)tiga warna lainnya. Sederhana reshapemembawa vektor linier kembali ke bentuk matriks, yang dipetakan ke warna yang diinginkan menggunakanind2rgb . Akhirnya,imagesc, menunjukkan gambar, ditampilkan pada ukuran gambar default (yang cukup besar untuk persyaratan). Seperti keberuntungan akan memilikinya, imagesctidak keberatan nilai berada di luar rentang yang ditentukan, sehingga eyedapat digunakan untuk menginisialisasi matriks karena keduanya 1dan 0dianggap merah.

masukkan deskripsi gambar di sini

Sanchises
sumber
1
Ups, lupa untuk memperbaiki Anda ... Saya suka semua trik kecil Anda :-)
CG.
Benarkah warna acak tidak pernah merah di versi yang diperbarui? Tampaknya seperti itu setidaknya dalam Oktaf (tidak memiliki MATLAB).
Stewie Griffin
@StewieGriffin Saya pasti sudah tidur ketika saya membuat ini. Anda tentu saja benar - dan itu menyelamatkan saya satu byte juga ...
Sanchises
(buat itu dua byte)
Sanchises
2

Python 3.6 (316 Bytes)

Menggunakan kode warna ANSI dan string literal berformat baru dari Python 3.6 ( PEP 489 ) ( f"{X}"keajaiban).

Kalau tidak, itu hanya cukup dasar, tetapi python dikaburkan. Lebar dan Tinggi dilewatkan sebagai argumen pada baris perintah.

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)

masukkan deskripsi gambar di sini

Jonas Schäfer
sumber
Anda dapat menyimpan 6 byte dengan menggunakan w,h=map(int,sys.argv[1:]), membongkar karya dengan iterable (dengan ukuran yang tepat), panggilan ke daftar berlebihan.
Sebastian Riese
Beberapa byte ke bawah: "\x1b["=> "\33["(menggunakan octal alih-alih hex escapes), maka singkatan X dan string format sebenarnya membuatnya lebih lama (dan dengan menghilangkan f""Anda mendapatkan kompatibilitas dengan python3). (ini akan membawanya ke 301 byte).
Sebastian Riese
Ups, Anda menggunakan {x}sekali ... tetapi Anda masih menang dengan menyingkirkan X.
Sebastian Riese