O desafio
GIFs são o formato de imagem mais comum para animação e são usados bastante nas mídias sociais atuais. Para o objetivo deste desafio, vou redefinir o que um GIF pode ser. Esse desafio exigirá que você pegue uma matriz 3D que contenha algum tipo de representação de uma 'imagem' 2D e itere através dela, exibindo uma animação. Essa animação pode ser feita em qualquer lugar, em um GIF, no seu console, em uma GUI, etc; a entrega não importa, desde que seja animada.
A entrada
- Uma matriz 3D onde os dados dentro de alguma forma representam uma imagem 2D.
- A matriz pode conter dados RGB, dados verdadeiros / falsos ou qualquer outra coisa que você achar melhor.
- Também estou bem com você modificando-o para uma matriz 2D de seqüências de caracteres ou algo semelhante, mas a animação deve ser uma animação 2D .
- O tempo entre cada quadro em um formato de sua escolha (segundos, milissegundos, etc ...).
- As pessoas me perguntam se têm ou não que incluir a duração da duração. Minha resposta é "meh", desde que você seja capaz de mostrar animação. Estou mais preocupado que você adira ao parâmetro "Matriz" do que este, o que significa que não há animações aleatórias.
A saída
- Uma sequência de saída perfeitamente iterada que se parece com uma animação 2D com o atraso correto em cada transição com base na entrada de valor.
As regras
- A saída pode ser, mas não está limitada a:
- Imagem GIF.
- Animação GUI (meu exemplo).
- Animação no console.
- Honestamente, qualquer "animação" que você achar conveniente, desde que siga as regras abaixo.
- Ao produzir sua imagem, você deve limpar o console antes de mostrar o próximo quadro, não pode imprimi-las apenas sequencialmente.
- Emular um console "claro" também é aceitável, desde que pareça uma animação contínua (veja a dica no meu exemplo para obter mais informações sobre o que quero dizer).
- Independentemente da implementação, sua animação deve repetir para sempre ou até parar.
- O "looping" pode ser tão simples quanto
while(true){}
uma recursão infinita; você pode assumir que o usuário deseja visualizar esta obra-prima até clicar em "ctrl + c".
- O "looping" pode ser tão simples quanto
- Você deve poder manipular 'imagens' 2D de qualquer tamanho, se o seu idioma for limitado por tamanhos de buffer, isso é aceitável e você pode declarar isso na sua explicação.
- As brechas padrão não são permitidas.
Exemplo de E / S
Entrada (matriz 3D, atraso)
f([
[[1,0,0],
[0,0,0],
[0,0,0]],
[[0,0,0],
[0,1,0],
[0,0,0]],
[[0,0,0],
[0,0,0],
[0,0,1]],
], 1)
Saída (exemplo, 2020 bytes - Java)
import javax.swing.JFrame;
import javax.swing.JTextArea;
/**
* Simple GIF class to animate a 3D integer array in a swing text area.
* (Clearing the console in java isn't something you really do, so I chose
* java on purpose to make it an extremely ungolf-able answer that someone
* wouldn't bother to steal).
*/
public class Gif implements Runnable {
/**
* The output area.
*/
private final JTextArea area;
/**
* The list of images.
*/
private final int[][][] images;
/**
* The delay between image transitions.
*/
private final long transitionDelay;
/**
* Main method, instantiates a GIF object and runs it.
* @param args Does absolutely nothing.
*/
public static void main(String[] args) {
final int[][][] images = {{{1,0,0},{0,0,0},{0,0,0}},{{0,0,0},{0,1,0},{0,0,0}},{{0,0,0},{0,0,0},{0,0,1}}};
final long transitionDelay = 1000L;
new Thread(new Gif(images, transitionDelay)).start();
}
/**
* Constructor for a GIF, takes in a 3D array of images and a transition
* delay to wait between transitioning the images.
* @param images The list of images.
* @param delay The delay between each image.
*/
public Gif(int[][][] images, long transitionDelay) {
this.images = images;
this.transitionDelay = transitionDelay;
this.area = new JTextArea();
final JFrame frame = new JFrame("It's a GIF!");
frame.setSize(10,100);
frame.add(area);
frame.setVisible(true);
}
/**
* When run, it will alter the area to imitate an animated GIF.
*/
@Override
public void run() {
while (true) {
for (int i = 0; i < images.length; i++) {
final StringBuffer frame = new StringBuffer();
for (int j = 0; j < images[i].length; j++) {
for (int k = 0; k < images[i][j].length; k++) {
frame.append("" + images[i][j][k]);
}
frame.append("\n");
}
this.area.setText(frame.toString());
try{Thread.sleep(transitionDelay);}catch(Exception e){}
this.area.setText("");
}
}
}
}
Isso resulta em uma GUI de balanço aparecendo, animando a matriz:
SUGESTÃO: Use um idioma em que a limpeza do console seja possível ou especifique por que o que você está fazendo terminará com um resultado que se parece com uma animação no idioma escolhido. Acho que alguns idiomas têm tamanhos de buffer padrão em seus consoles, você pode usar isso para sua vantagem, mas espero uma explicação ou exemplo. Só porque eu mostro minha animação como uma string, você não precisa; Eu poderia facilmente usar 0 para preto e 1 para branco e criar um GIF real.
A julgar
Isso é código-golfe, menor número de bytes ganhos (entradas excluídas).
Marcarei com +1 qualquer pessoa que use um idioma de uma maneira interessante ou inesperada.
Respostas:
MATL ,
161211 bytesEntrada é uma matriz de células 2D. Por exemplo:
O tempo de pausa é o
1
do código. Pode ser alterado para qualquer número real, como.5
ou .2.Experimente no MATL Online! (Se não funcionar, atualize a página e pressione "Executar" novamente.)
A entrada também pode ser uma matriz de células de matrizes de caracteres 2D. Por exemplo:
Experimente este também!
Explicação
fonte
[0.2 0 0.2;0 0.2 0] ...
, e assim reduzirxx
ax
, evitar1G
e2G
? Eu acredito que adere às regras. Você precisa adicionar alguns bytes para converter0.2
em1
, a menos que queira0.2
pular naturalmente, e alguma maneira de armazenar o valor de pausa. Eu ainda acho que poderia reduzir a contagem de bytes embora :)Oitava,
565447 bytesRemovida a possibilidade de inserir o tempo de pausa como parte da matriz de entrada. Fiquei muito satisfeito com isso, então dê uma olhada no histórico de edições, se você quiser dar uma olhada. Esta solução é 7 bytes mais curta.
A entrada será mais ou menos assim:
[4 0 0 4;0 4 4 0;4 0 0 0]
onde será uma matriz de dimensões 3x4 e o tempo de pausa desejado é de 4 segundos.Ele exibe um gráfico como o abaixo, mas alterna entre mostrar os valores verdadeiro e falso da entrada. Portanto, todos os pontos azuis se tornarão brancos na próxima iteração e todo o branco se tornará azul.
No gráfico abaixo, usei a entrada
rand(10,10)>0.6*2
. Isso significa que ele terá dimensões 10x10 e todos os elementos da matriz aleatória maiores que 0,6 serão verdadeiros. Depois disso, multiplico pelo tempo de pausa desejado, 2 segundos. Eu usei uma matriz aleatória aqui, mas também poderia ter criado a matriz manualmente.Como o Octave não está instalado neste computador, fiz uma pequena alteração para que isso funcionasse no MATLAB. É exatamente o mesmo princípio, mas
n=~n
não funciona no MATLAB.fonte
sed
141 13490-51 graças a seshoumara
Entrada: Primeiro, cada quadro é separado por uma linha com um único espaço e, em seguida, exibe o próximo quadro depois que cada linha em branco é recebida (se parece com um flipbook). Mínimo de 3 quadros.
Por padrão, no meu sistema (Windows 7), quando abro o cygwin, ele tem 24 linhas na vertical. Entre os quadros, sempre há pelo menos muitas linhas em branco impressas. Isso efetivamente limpa a tela.
Mais de 1/3 dos bytes vêm da limpeza do console. Tenho certeza de que há uma maneira melhor.
fonte
p
comando como parte des///p
, mais 6 bytes removendo/^\n/!
antesP
, o que acho que não é necessário. Pelo esforço, +1, embora eu também tenha certeza de que há uma maneira melhor.sed
, mas por algum motivo não funciona comcat
ouecho
.echo -e "\e[2Jtest"
. Com cat, o caractere de escape já deve estar no arquivo / entrada, tenteecho -e "\e[2Jtest"|cat -n
rolar para cima.GNU sed,
8884 + 1 (sinalizador n) = 85 bytesEdit: 3 bytes a menos, graças a Riley
O formato de entrada é um quadro de animação por linha. Para várias linhas de saída em um quadro, use vírgula como separador. Como eu executo o programa em um console Linux, o tamanho máximo da imagem disponível (medido em linhas e colunas) depende do tamanho da janela do terminal. A pausa entre dois quadros é realizada pelo comando sleep shell; para receber uma chamada de animação mais rápida
esleep 0.4
(segundos).A melhor parte é que eu apoio animação em cores! Para fazer isso, usei as chamadas ANSI Escape Sequences para controlar a fonte do texto, a cor do primeiro plano e do plano de fundo, além da posição do cursor, conseguindo limpar a tela antes de cada quadro (código
ESC[2J
). Para adicionar informações de cores, use o seguinte formato na entrada, que é melhor explicado aqui .Corre:
Exemplos: para cada teste, 2 ciclos de animação foram capturados na tela e salvos no formato GIF de imagem (desculpas pela baixa resolução)
0,4 segundos de pausa
1 segundo por padrão
Explicação:
fonte
1h;1d;H;
porH;1h;
Ruby,
8945 bytesO
^[
é um personagem de escape.Hexdump:
Economizou muitos bytes graças a @Jordan
fonte
->h,t{h.cycle{|x|puts"^[[2J",x.map(&:join)}}
Lua ( LÖVE ),
296287 bytesExemplo de uso
Saída : https://youtu.be/0kDhPbbyG9E
fonte
SmallBasic, 167 bytes
Como parâmetro, defina e defina a variável global i! Infelizmente, o SmallBasic não suporta parâmetros para próprias sub-rotinas.
fonte