Tangga ASCII Yakub Animate

23

Anda mungkin pernah melihat Tangga Yakub di museum sains anak-anak. Jika Anda tidak terbiasa dengan tampilannya, ada beberapa gambar dan contoh video di Wikimedia Commons . Tantangannya hari ini adalah membuat versi animasi ASCII dari gadget listrik. Pada akhirnya, akan terlihat seperti ini:

Contoh TanggaGIF


Konstruksi Tangga

Berikut adalah bentuk dasar tangga dengan tinggi ( H ) 6:

6   \            /
5    \          /
4     \        /
3      \      /
2       \    /
1        \  /
0         ¯¯

Angka-angka di sebelah kiri hanya menunjukkan nomor baris untuk contoh ini dan tidak boleh dimasukkan dalam output. Kami akan merujuk ke baris yang diberikan oleh angka ( R ). Baris 0 adalah bagian bawah ¯¯. Setiap baris 1 hingga H terdiri dari empat bagian:

  • Ruang (U + 0020) diulang ( H - R ) kali
  • Garis miring \(U + 005C)
  • Ruang (U + 0020) diulang (2 * R ) kali
  • Garis miring ke depan /(U + 002F)

Baris 0 identik kecuali kedua garis miring diganti dengan macron ¯(U + 00AF). Mengejar spasi putih pada akhir setiap baris atau di bawah tangga adalah OK. Ruang putih terkemuka tidak.


Konstruksi busur

Setelah tangga dibangun, Anda dapat membuat busur antara sisi kiri dan kanan. Satu busur sepenuhnya dalam satu baris dan menggantikan ruang antara yang memimpin \dan yang tertinggal /. Oleh karena itu, baris 2 akan memiliki 4 karakter di busurnya, baris 3 akan memiliki 6, dan seterusnya. Setiap busur disusun menggunakan aturan berikut:

  • Satu-satunya karakter yang diizinkan adalah _/¯\(U + 005F, U + 002F, U + 00AF, U + 005C)
  • Untuk memastikan penampilan yang halus, setiap ¯atau /harus diikuti oleh ¯atau\
  • Untuk memastikan penampilan yang halus, setiap _atau \harus diikuti oleh _atau/
  • Dua aturan di atas berlaku untuk tepi tangga juga
  • Tiga aturan di atas secara efektif berarti bahwa karakter pertama dalam arc harus _atau /dan karakter terakhir harus _atau \( \¯\_//tidak valid pada kedua ujungnya tetapi \_/¯\/OK)
  • Harus ada peluang tidak nol untuk setiap karakter yang diizinkan terjadi pada titik tertentu
  • Setiap busur independen dari setiap busur lainnya

Animasi

Kehidupan busur tunggal dibuat dengan memulainya di baris 1 dan "memindahkannya" satu baris pada satu waktu hingga mencapai puncak. Yaitu, pertama menghasilkan busur di baris 1, kemudian mengaturnya kembali ke spasi dan menghasilkan busur di baris 2, dan seterusnya. Diberikan sejumlah busur untuk ditampilkan ( N ), perlihatkan umur lengkap dari banyak busur itu satu per satu menggunakan pedoman berikut:

  • Hanya satu busur yang harus "hidup" pada satu waktu. Busur berikutnya tidak dapat mulai sampai busur saat ini mencapai puncak dan kemudian padam.
  • Setiap baris kehidupan busur harus ditampilkan tepat satu frame
  • Seharusnya ada satu bingkai hanya tangga dasar (tanpa busur) sebelum busur baru dimulai (opsional sebelum busur pertama)
  • Animasi harus menunjukkan kehidupan penuh busur N. Jika N = 0, itu harus menghidupkan busur acak selamanya sampai berhenti.
  • Jika N > 0, Anda masih dapat mengulang animasi untuk selamanya tetapi harus berupa loop dengan busur yang sama berulang kali. (Contoh GIF di bagian atas posting ini memiliki H = 6 dan N = 3 tetapi berulang selamanya.)
  • Animasi harus ada di tempat. Artinya, setiap frame harus sepenuhnya menimpa frame berikutnya dan berada di lokasi yang sama.
  • Panjang setiap frame bisa menjadi apa pun yang Anda inginkan tetapi membuatnya ditonton oleh manusia (yaitu, gunakan akal sehat Anda: 0,01s / frame dan 30s / frame keduanya tidak dapat diterima.)

Input output

  • Input dan Output dapat dalam format standar apa pun
  • Anda dapat mengekspor GIF, menulis teks ke layar, mengeluarkan satu file untuk setiap frame, atau cara lain yang masuk akal
  • Celah standar dilarang
  • Ketinggian tangga H akan menjadi bilangan bulat positif
  • Jumlah busur untuk menunjukkan N akan menjadi bilangan bulat non-negatif
  • Baik H dan N diambil sebagai input dalam urutan apa pun yang Anda pilih (Harap sertakan urutan dalam jawaban Anda)

Kondisi Menang

Ini adalah sehingga kode terpendek menang.

Bak pasir

Toast insinyur
sumber
1
Bisakah busur dihasilkan simetris oleh pusatnya? Saya tidak bisa melihat batasan untuk itu dalam aturan
Dead Possum
Bisakah saya mencetak setiap frame satu sama lain ke konsol?
TFeld
@DeadPossum Saya berpikir Anda benar meskipun faktanya itu tidak terlihat sangat kilat-y tetapi sebenarnya tidak diizinkan oleh kombinasi dua aturan: the first character in the arc must be _ or / and the last character must be _ or \ dan There must be a non-zero chance for each allowable character to occur at a given point. Agar simetris, karakter pertama dan terakhir harus _setiap waktu yang berarti tidak ada peluang untuk terjadi /atau `\`.
Engineer Toast
@TFeld Sejauh setiap frame muncul di lokasi yang sama di layar, ya. Itu berarti Anda harus menghapus konsol (atau mungkin gulir ke bawah, jika itu memungkinkan) setiap kali.
Engineer Toast
2
Apakah persyaratan macron berarti bahwa QBasic tidak dapat bersaing? Menggunakan CP437 , di mana titik kode 0xAFadalah ».
DLosc

Jawaban:

5

Python 2 , 287 271 270 276 275 byte

import time,random
r,n=input()
c=n*-~r or-r
while c:
 c-=1;L=[list(' '*i+'\\'+'  '*(r-i)+'/')for i in range(r)];x=c%-~r;time.sleep(1);y=x+1;exec"L[x][y]=random.choice('\xaf/\_'[L[x][y-1]in'\_'::2][y==2*r-x:]);y+=1;"*2*(r-x)
 for l in['']*99+L+[' '*r+'\xaf'*2]:print''.join(l)

Cobalah online!

Tidak menghapus layar pada tio, tetapi bekerja di konsol.

Biarkan berjalan:

masukkan deskripsi gambar di sini

TFeld
sumber
Agak licik tetapi Anda bisa menggunakan print'\n'*99alih-alih os.system('cls')dan kehilangan osimpor. Masih tidak berfungsi di TIO tetapi berfungsi di konsol Windows dan Linux.
ElPedro
1
Seharusnya ada satu frame hanya tangga dasar (tanpa busur) sebelum busur baru dimulai (opsional sebelum busur pertama)
wastl
5
Saya pikir Anda menggunakan tanda hubung (U + 002D) bukan macron (U + 00AF). Saya tidak berpikir itu akan meningkatkan jumlah byte Anda untuk memperbaikinya. Juga, seperti yang ditunjukkan @wastl, tidak ada bingkai tangga kosong di antara busur.
Engineer Toast
Baris bawah menggunakan macron tetapi busur tidak
Engineer Toast
1
@ Engineer Tetap sekarang :)
TFeld
4

JavaScript (ES6), 245 byte

f=(o,h,n,i=0)=>(o.innerText=[...Array(h+1)].map((_,j)=>` `.repeat(j)+(j<h?`\\${[...Array(w--*2)].map((_,k)=>h+~j-i?` `:k>w*2|Math.random()<.5?s[s=t,1]:s[s=`¯\\`,0],s=t=`/_`).join``}/`:`¯¯`),w=h).join`
`,(++i<h||--n)&&setTimeout(f,250,o,h,n,i%h))
Height: <input type=number min=1 value=6 id=h><br>Arcs: <input type=number min=0 value=3 id=n><br><input type=button value=Go! onclick=f(o,+h.value,+n.value)><pre id=o></pre>

Hitungan byte mengasumsikan penyandian ISO-8859-1.

Neil
sumber
Dimungkinkan untuk menguranginya menjadi 242 dengan mendefinisikan A=x=>[...Array(x)].map;di awal dan mengganti kedua penggunaan.
Bary12
@ Bary12 Anda tidak dapat kembali map, itu hanya properti Array.prototypedan tidak ada gunanya sendiri. Saya mencoba versi yang berfungsi tetapi semuanya keluar lebih dari 245 byte.
Neil
3

C (gcc) , 406 byte

#define p(X) printf(X),usleep(999)
#define x(X) do{s[X]=0;p(s);s[X]=' ';}while(0)
char c[2][2]={95,47,92,'¯'};R;i;j;k;a(){char s[2]={92,0};for(j=0;j<2*R-1;++j,p(s))*s=c[*s<50][rand()%2];*s=c[*s<50][0];p(s);}f(H,N){char s[99];for(i=0;i<99;++i)s[i]=' ';p("\e[s");for(i=0;;++i){i%=(N?N:i+1);srand(i^H^N);for(k=1;k<H;++k){for(R=H;--R;){x(H-R+1);p("\\");if(R==k)a();else x(2*R);p("/\n");}x(H);p(" ¯¯\n\e[u");}}}

Cobalah online!

Deskripsi:

#define p(X) printf(X),usleep(999)              // Define p to printf(p) + delay
#define x(X) do{s[X]=0;p(s);s[X]=' ';}while(0)  // Define x(X) to print X spaces
                                                // This uses a string s full of
                                                // spaces and adds the null
                                                // terminator where approrpiate
char c[2][2]={95,47,92,'¯'};                    // 2d array of 'next arc' options
R;i;j;k;                                        // Variables
a(){                                            // a() -> print arc for row R
    char s[2]={92,0};                           // s is a string of next char
                                                // initialize to backslash
    for(j=0;j<2*R-1;++j                         // loop over each character
            ,p(s))                              // printing s each time
        *s=c[*s<50][rand()%2];                  // set s to the next arc char
    *s=c[*s<50][0];                             // set s to the 'first' arc char
                                                // note that in definition of c
                                                // first means appropriate as
                                                // final character before /
    p(s);}                                      // print the last character
f(H,N){                                         // f(H,N) -> print jacob ladder
    char s[99];for(i=0;i<99;++i)s[i]=' ';       // this is the space string for x
    p("\e[s");                                  // ANSI terminal save position
    for(i=0;;++i){i%=(N?N:i+1);                 // loop i->N (or i->INT_MAX if N=0)
        srand(i^H^N);                           // seed random with i XOR H XOR N
        for(k=1;k<H;++k){                       // for each row (bottom to top)
            for(R=H;--R;){                      // for each row (top to bottom)
                x(H-R+1);p("\\");               // print left "    \"
                if(R==k)                        // if on the arc row
                    a();                        // print the arc
                else x(2*R);                    // otherwise print spaces
                p("/\n");}                      // finish off the row
            x(H);p(" ¯¯\n\e[u");}}}             // print bottom line and move back
LambdaBeta
sumber
Catatan: hanya benar-benar berfungsi di Xterm ... banyak terminal emulator tidak mendukung posisi save / restore.
LambdaBeta
Baris bawah adalah baris 0 dan hanya memiliki dua macron. Bukan itu \--/. Itu mungkin perbaikan yang mudah. Apakah Anda dapat menangkap dan memposting GIF yang berfungsi di Xterm?
Engineer Toast
Sayangnya saya tidak memiliki alat untuk melakukan itu (hanya bermain-main saat membangun di tempat kerja). Saya akan memperbarui dengan baris 0 yang benar, itu adalah perbaikan yang mudah.
LambdaBeta
Invalid: Seharusnya ada satu frame hanya tangga dasar (tanpa busur) sebelum busur baru dimulai (opsional sebelum busur pertama)
wastl
mengubah k = 1 ke k = 0 perbaikan yang ... biaya 0 byte. Akan segera diperbarui.
LambdaBeta
2

PowerShell , 347 319 byte

filter c{Param($h,$n)if($n-eq0){$n=-1}for($x=0;$x++-ne$n;){($h..1)|%{$l=(($h..1)|%{"$(" "*($h-$_))\$(" "*$_*2)/"})+"$(" "*$h)¯¯"
$r="Get-Random"
$i=0
$z=-join((0..(($h-$_)*2))|%{$i=switch($i%3){0{&$r 0,1}default{&$r 2,3}}"_/¯\"[$i]})+"_\\_"[$i]
$l[$_-1]=($l[$_-1]).Substring(0,$_)+"$z/"
cls
$l
Sleep -m 250}}}

Cobalah online!Tidak bisa $argsbermain bagus, jadi tautannya memanggil fungsi tanpa membersihkan konsol.

Tidak disatukan

filter c{
    Param($h,$n)
    if($n -eq 0){$n=-1} # inelegant swap to allow for an infinite loop. 
                        # Curse you zero-indexing!
    for($x=0;$x++-ne$n;)
    {
        ($h..1) | % {         
            $l=(($h..1)|%{ # (( double paren is needed to induce each line 
                           # as a new array element
                "$(" "*($h-$_))\$(" "*$_*2)/" # offset by total height. 
                                              # N spaces + rung + N*2 spaces + rung
            })+"$(" "*$h)¯¯" # last line is the floor of the ladder

            $r="Get-Random" # shorter to declare once and execute with & operator

            $i=0 # initialize $i so we choose only _ or / for the first char

            $z=-join( # build an electric ZAP!
                (0..(($h-$_)*2))|%{                    
                    $i = switch($i%3) { # choose next char based on previous selection
                        0{&$r 0,1}
                        default{&$r 2,3}
                    }    
                    "_/¯\"[$i]
                }
            )+"_\\_"[$i] # final char is \ or _ to rejoin the ladder        
            $l[$_-1]=($l[$_-1]).Substring(0,$_)+"$z/" # select one rung of the ladder 
                                                      # append an electric ZAP!                
            cls # clear the console
            $l  # display the ladder
            Sleep -m 250
        }
    }
}
Peter Vandivier
sumber
Ini hal yang kecil, tetapi baris paling bawah adalah tanda hubung bukannya macron. Ini adalah perubahan nol-byte$l=(($h..1)|%{"$(" "*($h-$_))\$(" "*$_*2)/"})+"$(" "*$h)¯¯"
Engineer Toast
1
¯ \ (° _o) / ¯ ups! ditukar dalam macron: p
Peter Vandivier
1
Saya tidak terlalu mengenal PowerShell, tetapi Anda dapat menghapus sebagian besar baris baru. Selain itu for($x=0;$x-ne$n;$x++)bisa for($x=0;$x++-ne$n;). Saya turun ke 324 byte (321 karakter) melakukannya. Tip untuk bermain golf di <semua bahasa> dan Tips untuk bermain golf di PowerShell mungkin menarik untuk dibaca juga.
Kevin Cruijssen
1
sleep 1menghemat sedikit (default -seconds) tetapi cukup lambat tapi masih masuk akal-ish, sleep -m 99cukup cepat tetapi juga masuk akal. Menghemat 5/1 byte tergantung pada apa yang Anda suka. Tidak memeriksa upaya Kevin tetapi functionuntuk filteradalah byte gratis juga.
Veskah
1

Ruby , 293 byte

m={}
"   __/\\_/¯¯\\/¯\\".chars.each_slice(3){|e|u,*v=e;m[u]=v}
a=->l,c{l<1?"/":(d=m[c].sample;c+a[l-1,d])}
n=gets.to_i
h=gets.to_i
o=0
while o<n||n<1
h.times{|i|puts (0...h).map{|j|" "*j+"\\"+a[2*(h-j),i==h-j-1?["_","/"].sample: " "]}*"\n";puts" "*h+"¯¯";sleep(0.3);puts"\n"*99}
o+=1
end

Cobalah online!

Saya di windows sehingga hanya mencetak banyak "\ n" untuk menghapus konsol. Membawa 2 argumen ndan hsebagai dua baris di stdin.

crashoz
sumber