Анимированные липкие легкие украшения

22

Это испытание в честь безвкусных рождественских огней в доме моих в законах.


Задача состоит в том, чтобы создать графический вывод, показывающий оформление в «реальном времени».

Видео (gif или другой формат) будет иметь n-m-m вертикальные и горизонтальные «огни». 5 <= m, n <= 40 . Размер и разрешение кадра могут варьироваться в зависимости от n и m , но должны быть не менее 50x50 пикселей для n, m = 5 (с векторной графикой все в порядке). Картинка с n=6и m=5будет выглядеть примерно так:

введите описание изображения здесь


Украшение:

Цвета:

Все огни будут иметь один из следующих 6 RGB-цветов {255,0,0}, {0,255,0}, {0,0,255}, {255,255,0}, {0,255,255}и {255,0,255}.

Анимация:

  • nи mбудут приняты в качестве входных данных в любом разумном формате и в порядке, который вам нравится
  • Изображение будет меняться каждый dt = 25 ms. Отклонения в порядке, если это связано с «внешними факторами», такими как ограничение в переводчике, медленный компьютер и т. Д.
    • Если невозможно установить шаг времени вручную, тогда шаг по умолчанию принят.
  • Все огни будут красными ( {255,0,0}) в t=0.
  • Всегда есть вероятность 5%, что первый свет (вверху слева) изменит цвет. Все цвета (кроме цвета, который он имеет в настоящее время) должны быть одинаково вероятными.
  • Каждый источник света (кроме первого) получит цвет источника света слева. Если источник света находится в крайнем левом углу, он получит цвет источника света в крайнем правом ряду выше. Огни пронумерованы, как показано ниже. Светлый номер kполучит цвет светового числа k-1.

     1  2  3  4  5  6
     7  8  9 10 11 12
    13 14 15 16 17 18
    
  • Вывод теоретически должен работать вечно (если только у вашего языка / интерпретатора нет каких-либо ограничений, препятствующих этому).

  • Пожалуйста, предоставьте образец не менее 5 секунд, желательно больше в ответе (это поощрение, а не требование). (Ссылка на TIO или аналогичный, конечно, тоже нормально: D)
  • Рамки, оси, линии сетки и т. Д. Принимаются.

6-по-5

введите описание изображения здесь

15-по-30

введите описание изображения здесь

Стьюи Гриффин
источник
Если интерпретатор работает медленно, следует отрегулировать время паузы, чтобы общее время между обновлениями изображения было таким же, как в примерах? Что делать, если пауза не нужна (код уже достаточно медленный)? Это спасло бы байты, возможно, против духа вызова
Луис Мендо
1
Поскольку вы выбрали цвета для простоты реализации - в таких языках, как QBasic, которые имеют ограниченный встроенный набор цветов, допустимо ли использовать цвета, наиболее близкие к указанным вами? (Красный, зеленый, синий, желтый, голубой, пурпурный)
DLosc
Если невозможно использовать указанные цвета, тогда да, можно использовать самые близкие альтернативы. Если это немного дольше, то нет. r,g,y,b,и т.д. короче на нескольких языках.
Стьюи Гриффин
@LuisMendo, извиняюсь за поздний ответ. Мне нравится, как ты сделал это в своем ответе. Было бы хорошо использовать 25 мс, даже если это замедлит анимацию. Я избежал, drawnowкогда я реализовал это в MATLAB, так как результат был слишком медленным. Я думаю, что ответ должен быть следующим: если это проектный выбор, когда интерпретатор имеет фиксированное минимальное разрешение по времени> = 25 мс, тогда все в порядке. Если это из-за плохой / простой реализации, онлайн-переводчика, который перегружен / медленен и т. Д., То это не в порядке.
Стьюи Гриффин
1
@ Stewie Понял, спасибо. И хороший вызов!
Луис Мендо

Ответы:

6

JavaScript / CSS / HTML, 436 байт

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 байт

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

объяснение

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

Создайте начальную доску в 1D, заполненную красным. Храните это в b.

Pause@.025

Пауза для 25 мс

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

Если (псевдо) случайное действительное число меньше 0,06, замените первый элемент bна длину 3списка случайной выборки {1,1,0,0}. (т.е. любой из{1, 1, 0}, {1, 0, 1}, {1, 0, 0}, {0, 1, 1}, {0, 1, 0}, {0, 0, 1} )

b=RotateRight@b

Циклический поворот вправо.

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

Измените значение первой ячейки на значение второй ячейки (то есть отмените смещение первой ячейки)

Partition[ ... ;b,#]

Перегородка bв (высота).

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

Сделайте это в динамическом (постоянно обновляемом) изображении, ширина которого составляет 50 (ширина)

Версия сотового автомата (186 байт)

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

Пример вывода (входы: 16, 10)

введите описание изображения здесь

Юнг Хван Мин
источник
6

MATLAB, 255 210 байт

Это мой первый гольф, так что, вероятно, будут сделаны улучшения.

Спасибо Луису за помощь в экономии 45 байт :)

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

Объяснение:

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

К сожалению, это не сохраняет анимацию, она просто запускает ее. Для того, чтобы сохранить его, мне либо нужна программа захвата экрана, либо переписать все это используя imwrite. Вместо этого я предоставлю две фотографии, показывающие разное время n=15,m=30.

введите описание изображения здесь

введите описание изображения здесь

CG.
источник
1
Некоторые предложения по игре в гольф: dec2bin([4 2 1 6 3 5])-48вместо [1 0 0;0 1 0;0 0 1;1 1 0; 0 1 1;1 0 1]. .95вместо 0.95. Вы также можете заменить .95на .94и избавиться от него k=k(k~=r);(потому что 0,94 + 0,06 / 6 = 0,95; см. Мой ответ для более подробного объяснения)
Луис Мендо
1
Еще лучше c=dec2bin(1:6)-48, поскольку порядок не имеет значения
Луис Мендо
Хороший первый ответ! Тем не менее, я боюсь, что обошел вас на 40% .
Sanchises
Гольф немного вниз :) Спасибо за помощь, Луис. ! :) Молодцы Санчизы!
CG.
4

MATL , 52 47 байт

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

Ввод является массивом [ncols nrows]. На выходе получается фигура с векторной графикой.

Пример прогона для 15 столбцов × 10 строк:

введите описание изображения здесь

Как это работает

Время паузы было установлено равным 15 мс (для того же количества байтов, что и 25 мс), чтобы попытаться компенсировать время обработки.

Чтобы сохранить цвет с вероятностью 19/20 (измените его на 1/20), действуем следующим образом:

  • С вероятностью 47/50 мы сохраняем цвет.
  • С вероятностью 3/50 мы выбираем новый цвет, равномерно выбранный среди 6 цветов. Может случиться так, что «новый» цвет будет таким же, как старый, и это происходит с вероятностью 1/6.

Таким образом, вероятность сохранения цвета составляет 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 байт

Примечание . Показанный GIF имеет более старую версию, которая хороша тем, что не отображает оси (см. Историю редактирования), но была очень медленной из-за реализации imshow. Для текущей версии ответ MATLAB Челси Г. или ответ MATL Луиса Мендо показывают тот же результат, что и моя текущая версия.

Размер принимается как 2x1вектор, поэтому назовите его, например:

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

Этот ответ использует тонкости языка MATLAB. Например, xинициализируется как m x nнулевая матрица, но так называемое линейное индексирование допускает круговое смещение с одномерными индексами. Слабая типизация допускает умножение с помощью логики, что позволяет ifизбегать операторов (трюк, который я активно использовал еще во времена программирования на калькуляторе TI-84). Даже если цветовая карта читается построчно, MATLAB рассматривает ее как нормальную матрицу, поэтому eye(3)ее можно использовать для создания красного, зеленого и синего 1-eye(3)цветов , а также трех других цветов. Простое reshapeвозвращает линейный вектор обратно в матричную форму, которая сопоставляется с желаемыми цветами с помощью ind2rgb. В заключение,imagesc, показывает изображение, отображаемое с размером фигуры по умолчанию (достаточно большим для требований). По счастливой случайности imagescзначения не выходят за пределы указанного диапазона, поэтому eyeмогут использоваться для инициализации матрицы, поскольку оба 1и 0считаются красными.

введите описание изображения здесь

Sanchises
источник
1
Ой, забыл объявить тебя ... Я люблю все твои маленькие хитрости :-)
CG.
Верно ли, что в обновленной версии случайный цвет никогда не бывает красным? Похоже, что так в Октаве по крайней мере (нет MATLAB).
Стьюи Гриффин
@ StewieGriffin Я, должно быть, спал, когда сделал это. Вы, конечно, совершенно правы - и это также спасло мне байт ...
Sanchises
(сделать это два байта)
Sanchises
2

Python 3.6 (316 байт)

Использование цветовых кодов ANSI и новых форматированных строковых литералов Python 3.6 ( PEP 489 ) ( f"{X}"магия).

В остальном это просто довольно простой, но запутанный питон. Ширина и Высота передаются в качестве аргументов в командной строке.

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)

введите описание изображения здесь

Йонас Шефер
источник
Вы можете сэкономить 6 байтов, используя w,h=map(int,sys.argv[1:])распаковку работ с любой итерацией (нужного размера), обращение к списку излишне.
Себастьян Рисе,
Еще несколько байтов вниз: "\x1b["=> "\33["(используя восьмеричные вместо шестнадцатеричных escape-кодов), затем сокращение X и строки формата фактически делают его длиннее (и, избавившись от него, f""вы получаете совместимость с любым python3). (это уменьшит его до 301 байта).
Себастьян Рисе,
К сожалению, вы используете {x}один раз ... но вы все равно выиграете, избавившись от X.
Себастьян Рисе,