Ayo Animasi!

8

Tantangan

GIF adalah format gambar yang paling umum untuk animasi, dan digunakan cukup banyak di media sosial saat ini. Untuk tujuan tantangan ini, saya akan mendefinisikan kembali seperti apa GIF itu. Tantangan ini akan mengharuskan Anda untuk mengambil dalam array 3D yang berisi semacam representasi 'gambar' 2D dan beralih melalui mereka, menampilkan animasi. Animasi ini dapat dilakukan di mana saja, di GIF, di konsol Anda, di GUI, dll; pengiriman tidak masalah, asalkan animasi.

Input

  • Array 3D di mana data di dalamnya mewakili gambar 2D.
    • Array dapat berisi data RGB, data benar / salah atau apa pun yang Anda inginkan.
    • Saya juga baik-baik saja dengan Anda membenamkannya ke array 2D string atau sesuatu yang serupa, tetapi animasi harus menjadi animasi 2D .
  • Waktu antara setiap frame dalam format yang Anda pilih (Detik, Milidetik, dll ...).
    • Orang-orang bertanya kepada saya apakah mereka HARUS memasukkan panjang durasi. Jawaban saya adalah "meh", selama Anda dapat menampilkan animasi. Saya lebih khawatir Anda mematuhi parameter "Array" daripada yang ini, artinya tidak ada animasi acak.

Hasil

  • Urutan output yang diulang mulus yang terlihat seperti animasi 2D dengan penundaan yang tepat pada setiap transisi berdasarkan pada input nilai.

Aturan

  • Output bisa, tetapi tidak terbatas pada:
    • Gambar GIF.
    • Animasi GUI (contoh saya).
    • Animasi dalam konsol.
    • Jujur saja, "animasi" apa saja yang Anda inginkan, asalkan mengikuti aturan di bawah ini.
  • Saat mengeluarkan gambar Anda, Anda harus menghapus konsol sebelum menunjukkan bingkai berikutnya, Anda tidak bisa hanya mencetaknya secara berurutan.
    • Meniru konsol "jelas" juga dapat diterima, asalkan terlihat seperti animasi yang mulus (lihat petunjuk di bawah contoh saya untuk informasi lebih lanjut tentang apa yang saya maksud).
  • Terlepas dari implementasi, animasi Anda harus berulang selamanya, atau sampai berhenti.
    • "Perulangan" dapat sesederhana while(true){}atau rekursi tak terbatas, Anda dapat menganggap pengguna ingin melihat karya besar ini sampai mereka menekan "ctrl + c".
  • Anda harus dapat menangani 'gambar' 2D ukuran apa pun, jika bahasa Anda dibatasi oleh ukuran buffer, ini dapat diterima dan Anda dapat menyatakan ini dalam penjelasan Anda.
  • Celah standar tidak diijinkan.

Contoh I / O

Input (Array 3D, Tunda)

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)

Output (Contoh, 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("");
            }
        }
    }
}

Ini menghasilkan GUI ayunan yang muncul, menganimasikan array:

Bingkai satu Bingkai Dua Bingkai Tiga

PETUNJUK PETUNJUK: Gunakan bahasa yang memungkinkan pembersihan konsol, atau tentukan mengapa apa yang Anda lakukan akan berakhir dengan hasil yang terlihat seperti animasi dalam bahasa yang Anda pilih. Saya pikir beberapa bahasa memiliki ukuran buffer default pada konsol mereka, Anda dapat menggunakan ini untuk keuntungan Anda, tetapi saya mengharapkan penjelasan atau contoh. Hanya karena saya menampilkan animasi saya sebagai string, Anda tidak harus; Saya bisa saja dengan mudah menggunakan 0 untuk hitam dan 1 untuk putih dan membuat GIF nyata.

Menilai

Ini adalah kode-golf, kemenangan jumlah byte terendah (input tidak termasuk).
Saya akan memberi +1 kepada siapa saja yang menggunakan bahasa dengan cara yang keren atau tidak terduga.

Guci Gurita Ajaib
sumber
Berapa banyak baris yang harus "jelas" seharusnya? Apakah bisa sama dengan jumlah karakter per baris?
Riley
Tantangan serupa dengan input yang lebih ketat: codegolf.stackexchange.com/questions/27101/…
luser droog
@Riley Saya tidak yakin saya mendapatkan apa yang Anda minta. Yang jelas pada dasarnya adalah untuk menjaga output pada jalur yang sama; kode Anda mungkin tidak benar-benar "menghapus" apa pun, tetapi ganti baris juga. Saya tidak peduli bagaimana Anda menyelesaikan animasi, lebih dari itu pada dasarnya berfungsi menggunakan bingkai.
Magic Octopus Guci
@luserdroog Saya belum melihat yang itu, tapi saya juga melihat satu di "buat snowscene" juga, tapi saya juga tidak melihat cukup dekat untuk menjamin tidak memposting ini.
Magic Octopus Mm
1
@carusocomputing Jangan khawatir, lebih dari senang untuk melakukan pemeriksaan tata bahasa. Ngomong-ngomong, dalam hal bahasa apa yang digunakan untuk animasi, apakah itu penting jika tidak lagi digunakan secara populer?
Monomeeth

Jawaban:

3

MATL , 16 12 11 byte

`G@)D1Y.XxT

Input adalah array sel 2D. Sebagai contoh:

{[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]}

Waktu jeda adalah 1dalam kode. Itu bisa diubah ke bilangan real apa saja, seperti .5atau `.2.

Cobalah di MATL Online! (Jika tidak berhasil, segarkan kembali halaman dan tekan "Run" lagi.)

Input juga bisa berupa larik sel array char 2D. Sebagai contoh:

{['x...';'+...';'....';'....'] ['+x..';'....';'....';'....'] ['.+x.';'....';'....';'....'] ['..+x';'....';'....';'....'] ['...+';'...x';'....';'....'] ['....';'...+';'...x';'....'] ['....';'....';'...+';'...x'] ['....';'....';'....';'..x+'] ['....';'....';'....';'.x+.'] ['....';'....';'....';'x+..'] ['....';'....';'x...';'+...'] ['....';'x...';'+...';'....']}

Coba yang ini juga!

Penjelasan

`       % Do...while
  G     %   Push input: cell array
  @     %   Push iteration index
  )     %   Index to obtain that cell. This uses modular indexing,
        %   so each cell is addressed cyclically
  D     %   Display
  1     %   Push 1: number of seconds to pause
  Y.    %   Pause for that many seconds
  Xx    %   Clear screen
  T     %   True. This is used as loop condition: infinite loop
        % End. Implicitly end do...while loop  
Luis Mendo
sumber
1
Bisakah Anda menyimpan beberapa byte menggunakan trik saya? Mengisi matriks dengan [0.2 0 0.2;0 0.2 0] ... , dan dengan demikian mengurangi xxuntuk x, dan menghindari 1Gdan 2G? Saya percaya itu mematuhi aturan. Anda perlu menambahkan beberapa byte untuk mengkonversi 0.2ke 1, kecuali jika Anda ingin 0.2melompat-lompat tentu saja, dan beberapa cara untuk menyimpan nilai menjeda. Saya masih berpikir itu bisa mengurangi hitungan byte :)
Stewie Griffin
1
@Weeingitfirst Terima kasih! Nah, tantangannya menentukan dua input: array dan jeda, jadi saya pikir keduanya diperlukan. Mari kita tunggu konfirmasi
Luis Mendo
2
Wow. Anda mengikuti brief dengan sempurna, bahkan mengikuti input. Ini jawaban yang sangat mengesankan. Pasti akan sulit dikalahkan, dan dibandingkan dengan jawaban yang tidak termasuk durasi jeda, ini pada dasarnya sempurna, bravo.
Magic Octopus Mm
1
@cocomputing Hebat! Terima kasih telah memberi tahu saya. Off 4 byte! Durasi masih bisa diubah, cukup jelas dalam kode
Luis Mendo
1
Saya akan jujur, saya ragu ini akan dikalahkan, jadi sampai pengiriman lebih lanjut saya menandai ini sebagai jawaban terbaik.
Magic Octopus Urn
2

Oktaf, 56 54 47 byte

Menghapus kemungkinan untuk memasukkan waktu jeda sebagai bagian dari matriks input. Saya sangat puas dengan itu, jadi lihatlah dalam riwayat edit jika Anda ingin melihatnya. Solusi ini lebih pendek 7 byte.

n=input('');while(any(n=~n))spy(n);pause(1);end

n=input('');  % Takes input as a matrix of zeros and ones

k=n(1);       % maximum of the input matrix is the desired pause time. Have to store
              % this, because n is soon to be messed with
              % NOTE: k=n(1); is not needed anymore, since the pause time can be hardcoded!

any(n=~n)     % Check if there are any truthy values in `n` (there is), and at the 
              % same time negate it, thus creating a matrix where all elements
              % alternates between 1 and 0.
while(any(n=~n))   % Loop as long as there are any non-zero elements (always some)
spy(n)        % Create a spy-plot where all non-zero elements are shown as a dot
pause(1)      % Pauses for k seconds
end           % ends the loop (will never happen, since it's infinite).

Input akan menjadi seperti ini:, di [4 0 0 4;0 4 4 0;4 0 0 0]mana ini akan menjadi matriks dimensi 3x4, dan waktu jeda yang diinginkan adalah 4 detik.

Ini menampilkan plot seperti di bawah ini, tetapi bergantian antara menunjukkan nilai input benar dan salah. Jadi semua titik biru akan menjadi putih di iterasi berikutnya, dan semua putih akan menjadi biru.

Dalam plot di bawah ini, saya menggunakan input rand(10,10)>0.6*2. Ini berarti ia akan memiliki dimensi 10x10, dan semua elemen dari matriks acak yang lebih besar dari 0,6 akan benar. Setelah itu saya gandakan dengan waktu jeda yang diinginkan, 2 detik. Saya menggunakan matriks acak di sini, tapi saya bisa membuat matriks secara manual juga.

Saya tidak memiliki Oktaf terinstal di komputer ini, jadi saya membuat perubahan kecil untuk membuat ini berfungsi di MATLAB. Ini prinsip yang sama persis, tetapi n=~ntidak berhasil di MATLAB.

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Stewie Griffin
sumber
2
@caruscomputing, apakah saya harus mengambil waktu jeda sebagai masukan, atau bisakah saya memilihnya sendiri? Misalnya selalu punya 1 detik?
Stewie Griffin
1
@carusocomputing, juga: Apakah boleh untuk membiarkan pengguna memilih waktu jeda, tetapi tidak memilikinya sebagai parameter terpisah? Menurut pendapat saya yang tidak begitu rendah hati, ini memenuhi syarat sebagai: "cara yang keren atau tidak terduga" ;-)
Stewie Griffin
1
Ya, saya sepenuhnya setuju, ini memenuhi syarat; selama Anda mengizinkan pengguna untuk menentukan beberapa parameter input, dan itu tidak sepenuhnya acak, saya pikir tidak apa-apa. Inti dari jeda adalah untuk dapat melihat animasi. Saya tidak ingin ada loop di mana orang menyatakan, "well, Anda tidak bisa melihatnya, tapi itu jelas menjiwai."
Magic Octopus Mm
1
Juga, saya menyukai kedua ide Anda; "TV Static Generator" adalah implementasi yang sangat unik, menggunakan pengacakan, yang bahkan tidak saya pertimbangkan. Ini juga mengesankan karena Anda berhasil mengambil iterasi pertama dan mematuhi brief. Pria yang baik.
Magic Octopus Mm
2

sed 141 134 90

-51 terima kasih kepada seshoumara

/^$/!{H;d}
:;/^$/g;s,^\n,,;s,$, ,;s,^,\d27[2J,p
:p;P;s,[^\n]*\n,,;/^ \n/!bp;N;s,[ \n]*,,;b

Input: Pertama-tama ambil setiap frame yang dipisahkan oleh garis dengan satu spasi kemudian tampilkan frame berikutnya setelah setiap baris kosong diterima (terlihat seperti flipbook). Minimal 3 frame.

Secara default pada sistem saya (Windows 7) ketika saya membuka cygwin memiliki 24 baris secara vertikal. Di antara frame, selalu ada setidaknya banyak garis kosong yang dicetak. Ini secara efektif membersihkan layar.

Lebih dari 1/3 byte berasal dari membersihkan konsol. Saya yakin ada cara yang lebih baik.

Riley
sumber
1
Anda dapat mengurangi 1 byte dengan memiliki pperintah pertama sebagai bagian dari s///p, ditambah 6 byte lebih banyak dengan menghapus /^\n/!sebelumnya P, yang saya pikir tidak diperlukan. Untuk upaya ini, +1, meskipun saya juga yakin ada cara yang lebih baik.
seshoumara
1
Setelah beberapa waktu menjelajahi internet, saya menemukan cara sederhana untuk memanipulasi kursor terminal, sehingga juga membersihkan layar: menggunakan ANSI Escape Sequences. Mekanisme ini juga digunakan untuk mencetak teks dalam warna. Silakan lihat jawaban saya untuk detail dan contoh penggunaan. Saya tidak tahu apakah mereka bekerja pada cygwin, tetapi Anda dapat mencoba.
seshoumara
@seshoumara Ini berfungsi di cygwin saat asalnya sed, tetapi karena alasan tertentu ia tidak bekerja dengan catatau echo.
Riley
Coba echo -e "\e[2Jtest". Dengan cat, karakter escape harus sudah ada di file / input, coba echo -e "\e[2Jtest"|cat -ndan gulir ke atas.
seshoumara
@seshoumara aku tahu itu pasti seperti itu. Terima kasih!
Riley
2

GNU sed, 88 84 + 1 (n flag) = 85 byte

Sunting: 3 byte lebih sedikit berkat Riley

H;1h;${:
g;s:\n.*::;H;x;s:[^\n]*\n::;x;y:,:\n:;s:^:ESC[2J:;s:ESC:\d27:gp;esleep 1
b}

Format input adalah satu bingkai animasi per baris. Untuk beberapa garis keluaran dalam bingkai, gunakan koma sebagai pemisah. Karena saya menjalankan program di konsol Linux, ukuran gambar maksimum yang tersedia (diukur dalam baris dan kolom) tergantung pada ukuran jendela terminal. Jeda antara dua frame dilakukan oleh perintah sleep shell; untuk mendapatkan panggilan animasi yang lebih cepat esleep 0.4(detik).

100,000,000            # The timer could be read from the input as well, but that
000,010,000            #would require a lot more bytes and I understand I'm allowed
000,000,001            #to hardcode the value.

Bagian terbaiknya adalah saya mendukung animasi warna! Untuk melakukan ini, saya menggunakan Sequence Escape ANSI yang disebut untuk mengontrol font teks, warna latar depan dan latar belakang, ditambah posisi kursor, sehingga dapat menghapus layar sebelum setiap frame (kode ESC[2J). Untuk menambahkan informasi warna, gunakan format berikut dalam input, yang lebih baik dijelaskan di sini .

ESC[$FORMATm$textESC[0m     # 'ESC' is an actual string, it is then replaced
                            #in sed by the character with the ASCII value 27

Lari:

sed -nf animate.sed input.txt

Contoh: untuk setiap tes, 2 siklus animasi ditangkap layar dan disimpan dalam format GIF gambar (permintaan maaf untuk resolusi rendah)

0,4 detik jeda Selamat ulang tahun!

1 detik secara default gerakan "pixel"

Penjelasan:

H;1h                           # read each line/frame and store them in hold space
${:                            # when the input was read, start a loop
   g                           # copy hold space to pattern space
   s:\n.*::                    # remove all except the first/current frame
   H                           # append frame to hold space
   x;s:[^\n]*\n::;x            # delete first frame from hold space
   y:,:\n:                     # replace all commas with a newline
   s:^:ESC[2J:;s:ESC:\d27:gp   # use an ANSI Escape Sequence to clear the screen
                               #and print frame in color
   esleep 1                    # wait 1 second
b}                             # repeat
seshoumara
sumber
Anda dapat menyimpan beberapa byte dengan menggantinya 1h;1d;H;denganH;1h;
Riley
@Riley Terima kasih, saya memperbarui kodenya.
seshoumara
Wow, ini lebih mendalam daripada yang lain, saya suka dukungan warna dan itu satu-satunya jawaban yang melakukan itu :). Penggunaan baris baru yang cukup unik juga. +1 untuk dukungan warna dan keunikan jawaban itu sendiri. Sejujurnya aku tidak akan percaya kalau aku tidak melihatnya sendiri!
Magic Gurita Guci
1

Ruby, 89 45 byte

f=->h,t{h.cycle{|x|puts"^[[2J",x.map(&:join)}}

Ini ^[adalah karakter pelarian.

Hexdump:

00000000: 663d 2d3e 682c 747b 682e 6379 636c 657b  f=->h,t{h.cycle{
00000010: 7c78 7c70 7574 7322 1b5b 324a 222c 782e  |x|puts".[2J",x.
00000020: 6d61 7028 263a 6a6f 696e 297d 7d         map(&:join)}}

Menyelamatkan banyak byte berkat @Jordan

TuxCrafting
sumber
@Doscosc Ah, ya, sedang memperbaiki
TuxCrafting
Anda dapat menyimpan banyak byte di sini. ->h,t{h.cycle{|x|puts"^[[2J",x.map(&:join)}}
Jordan
Jawaban yang bagus, juga sebagai FYI brief diubah, Anda tidak lagi harus mematuhi durasi sebagai input, karena ini membatasi bahasa yang mungkin. Anda hanya perlu berhenti sebentar agar animasi terlihat jelas.
Magic Octopus Urn
1

Lua ( LÖVE ), 296 287 byte

c=0;f=1;t=10;l=love
function l.load()loadstring('i='..arg[2])()s=tonumber(arg[3])end
function l.update(d)if c>s then
c=0;f=f==#i and 1 or f+1
end;c=c+d;end
function l.draw()for K,V in pairs(i[f])do
for k,v in pairs(V)do if v>0 then l.graphics.rectangle('fill',k*t,K*t,t,t)end
end
end
end

Contoh Penggunaan

love main.love '{{{1,0,0},{0,0,0},{0,0,0}},{{0,1,0},{0,0,0},{0,0,0}},{{0,0,1},{0,0,0},{0,0,0}},{{0,0,0},{0,0,1},{0,0,0}},{{0,0,0},{0,0,0},{0,0,1}},{{0,0,0},{0,0,0},{0,1,0}},{{0,0,0},{0,0,0},{1,0,0}},{{0,0,0},{1,0,0},{0,0,0}},{{1,0,0},{1,0,0},{0,0,0}},{{1,1,0},{1,0,0},{0,0,0}},{{1,1,1},{1,0,0},{0,0,0}},{{1,1,1},{1,0,1},{0,0,0}},{{1,1,1},{1,0,1},{0,0,1}},{{1,1,1},{1,0,1},{0,1,1}},{{1,1,1},{1,0,1},{1,1,1}},{{1,1,1},{1,1,1},{1,1,1}},{{0,0,0},{0,0,0},{0,0,0}}}' 1

Output : https://youtu.be/0kDhPbbyG9E

Master_ex
sumber
Hmm, saya tidak punya banyak eksposur ke lua, saya tidak tahu itu punya dukungan grafis juga, tetapi tahu itu memiliki kinerja yang hebat. Jawaban yang sangat menarik dan tidak terduga. Ini mungkin jawaban yang paling dekat dengan memungkinkan input berwarna berdasarkan angka yang dilewati. Juga jawaban pertama untuk tidak menggunakan ASCII, meskipun jumlah byte tinggi, pekerja besar +1 untuk keunikan.
Magic Octopus Mm
1
@cococuting Terima kasih! LÖVE adalah kerangka kerja untuk membuat game 2d. Anda harus memeriksanya :-)
Master_ex
Astaga, benarkah? Bisakah Anda menghubungkan saya dengan beberapa pekerja Anda yang lain? Saya benar-benar ingin melihatnya Bung.
Magic Octopus Mm
1

SmallBasic, 167 byte

Sebagai parameter, tentukan dan atur global var i! Sayangnya, SmallBasic tidak mendukung parameter untuk Sub-rutin sendiri.

sub animate
for j=0 to Array.getItemCount(i)
for k=0 to Array.getItemCount(i[0])
TextWindow.writeLine(i[j][k])
endfor
Program.delay(9)
TextWindow.clear()
endfor
endsub
Roman Gräf
sumber