Jacob'ın ASCII Merdiveni canlandırın


23

Jacob'ın Merdiveni çocuk bilim müzelerinde görmüş olabilirsiniz . Neye benzediklerini bilmiyorsanız, Wikimedia Commons'da birkaç resim ve video örneği vardır . Bugünün zorluğu, elektrikli aracın animasyonlu bir ASCII sürümünü oluşturmaktır. Sonunda, böyle bir şeye benzemelidir:

LadderGIFExample


Merdiven Yapımı

6 ( H ) yüksekliğinde bir merdivenin temel şekli :

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

Soldaki sayılar bu örnek için satır numarasını gösterir ve çıktıya dahil edilmemelidir. Belirli bir satıra numarası ( R ) ile değineceğiz . Satır 0 alttır ¯¯. Her 1 ila H sıraları dört bölümden oluşur:

  • Bir boşluk (U + 0020) tekrarlanan ( H - R ) kez
  • Bir eğik çizgi \(U + 005C)
  • Bir boşluk (U + 0020) tekrar edildi (2 * R ) kez
  • Bir eğik çizgi /(U + 002F)

Her iki eğik çizginin bir makron ¯(U + 00AF) ile değiştirilmesi dışında Satır 0 aynıdır . Her satırın sonunda veya merdivenin altında izleyen boşluk boş. Önde gelen boşluk değil.


Ark Yapısı

Merdiven inşa edildikten sonra, sol ve sağ taraf arasında yaylar oluşturabilirsiniz. Bir yay tamamen üst üstedir ve öncülük \ile takip arasındaki boşlukları değiştirir /. Bu nedenle, satır 2 yayında 4 karakter olacak, satır 3 ise 6 vb. Her yay aşağıdaki kuralları kullanarak oluşur:

  • İzin verilen tek karakterler _/¯\(U + 005F, U + 002F, U + 00AF, U + 005C)
  • Yumuşak bir görünüm sağlamak için, herhangi bir ¯ya da /bir ile takip edilmelidir ¯ya da\
  • Yumuşak bir görünüm sağlamak için, herhangi bir _ya da \bir ile takip edilmelidir _ya da/
  • Yukarıdaki iki kural, merdivenin kenarları için de geçerlidir.
  • Yukarıdaki üç kural etkili bir şekilde yaydaki ilk karakterin _veya /son karakterin olması gerektiği _veya \( \¯\_//her iki tarafta da geçersiz olduğu, ancak \_/¯\/tamam olduğu) anlamına gelir.
  • Her izin verilen karakterin belirli bir noktada gerçekleşmesi için sıfır olmayan bir şans olmalıdır.
  • Her yay, her yaydan bağımsızdır

Animasyon

Tek bir yayın ömrü, 1. satırdan başlayarak ve bir sıra yukarı çıkıncaya kadar bir satır yukarı “hareket ettirerek” yaratılır. IE, önce satır 1'de bir yay üretir, sonra onu boşluklara geri getirir ve satır 2'de bir yay oluşturur, vb. Gösterilecek çok sayıda yay verildiğinde ( N ), aşağıdaki yönergeleri kullanarak bir seferde bu birçok yayın ömrünü gösterin:

  • Herhangi bir zamanda sadece bir yay "canlı" olmalıdır. Bir sonraki yay, mevcut olanın üstüne gelene kadar başlayamaz ve sonra söner.
  • Arkın ömrünün her bir satırı, tam olarak bir kare için gösterilmelidir.
  • Yeni bir yay başlamadan önce (ilk yaydan önce isteğe bağlı) sadece temel merdivenlerden birinin (yaysız) bir çerçevesi olmalıdır.
  • Animasyon N yaylarının tüm ömrünü göstermelidir . Eğer K = 0 durana kadar, sonsuza kadar rasgele yay animasyon gerekir.
  • Eğer N > 0, sonsuza döngü animasyon hala may ama tekrar tekrar aynı arklar bir döngü olmalıdır. (Bu yazının tepesindeki GIF örneği H = 6 ve N = 3'tür, ancak sonsuza kadar döngüye girer.)
  • Animasyon yerinde gerçekleşmelidir. Yani, her kare bir sonraki karenin üzerine tamamen yazmalı ve aynı konumda olmalıdır.
  • Her bir karenin uzunluğu istediğiniz gibi olabilir ancak bir insan tarafından izlenebilir hale getirin (IE, sağduyunuzu kullanın: 0.01s / kare ve 30s / kare hem de kabul edilemez).

Giriş çıkış

  • Giriş ve Çıkış herhangi bir standart formatta olabilir
  • Bir GIF'yi dışa aktarabilir, ekrana metin yazabilir, her kare için tek bir dosya çıktısı alabilirsiniz ya da başka herhangi bir makul yol
  • Standart boşluklar yasaktır
  • H merdivenin yüksekliği pozitif bir tamsayı olacaktır.
  • N'yi gösterecek yay sayısı negatif olmayan bir tam sayı olacaktır
  • Hem H hem de N , seçtiğiniz herhangi bir sırada girdi olarak alınır (Lütfen cevabınıza sırayı ekleyin)

Kazanma Koşulu

Bu yani en kısa kod kazanır.

Kum havuzu


1
Merkezi tarafından simetrik yay üretilebilir mi? Kurallardaki kısıtlamayı göremiyorum
Dead Possum

Her kareyi birbiri ardına konsola yazdırabilir miyim?
TFeld

@DeadPossum Çok yıldırım gözükmeyecek olmasına rağmen haklı olduğunuzu düşünüyordum-ama aslında iki kuralın birleşmesine izin verilmiyor: the first character in the arc must be _ or / and the last character must be _ or \ ve There must be a non-zero chance for each allowable character to occur at a given point. Simetrik olması için, hem ilk hem de son karakterin _her seferinde olması gerekirdi; bu , ya /da “\” olma ihtimalinin sıfır olduğu anlamına gelir .
Mühendis Toast,

@TFeld Her kare ekranda aynı konumda göründüğü sürece, evet. Bu, her seferinde konsolu temizlemeniz (veya mümkünse aşağı kaydırmanız) anlamına gelir.
Mühendis Toast,

2
Makron gereksinimi, QBasic'in rekabet edemediği anlamına mı geliyor? Kullandığı cp437 kod noktası olan, 0xAFbir ».
DLosc

Yanıtlar:


5

Python 2 , 287 271 270 276 275 bayt

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)

Çevrimiçi deneyin!

Tio'daki ekranı temizlemiyor, ancak bir konsolda çalışıyor.

Çalışan Gif:

görüntü tanımını buraya girin


Biraz sinsi ama print'\n'*99onun yerine kullanabilir os.system('cls')ve osithalatı kaybedebilirsiniz . Hala TIO üzerinde çalışmıyor, ancak hem Windows hem de Linux konsollarında çalışıyor.
ElPedro

1
Yeni bir yay başlamadan önce (ilk yaydan önce isteğe bağlı) sadece temel bir merdivenin (
yaysız

5
Sanırım makroların yerine (U + 002D) tire (U + 002D) kullanıyorsunuz. Bayt sayısını düzeltmek için artacağını sanmıyorum. Ayrıca, @wastl'ın işaret ettiği gibi, yaylar arasında boş bir merdiven çerçevesi yoktur.
Mühendis Toast

Alt satırda makrolar kullanılıyor ancak yaylar kullanılmıyor
Engineer Toast

1
@EngineerToast Şimdi düzeltildi :)
TFeld

4

JavaScript (ES6), 245 bayt

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>

Bayt sayısı, ISO-8859-1 kodlamasını varsayar.


A=x=>[...Array(x)].map;Başlangıçta tanımlayarak ve her iki kullanım yerini değiştirerek onu 242'ye indirmek mümkündür .
Bary 12

@ Bary12 Geri dönemezsiniz map, bu sadece bir özelliktir Array.prototypeve kendi başına kullanılamaz. Çalışma sürümlerini denedim ancak hepsi 245 bayttan uzun çıktı.
Neil

3

C (gcc) , 406 bayt

#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");}}}

Çevrimiçi deneyin!

Açıklama:

#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

Not: yalnızca gerçekten Xterm'de çalışır ... birçok terminal emülatörü yalnızca kaydetme / geri yükleme konumunu desteklemez.
LambdaBeta

Alt satırda satır 0 ve sadece iki makro var. Öyle değil \--/. Bu muhtemelen kolay bir düzeltmedir. Xterm'de çalışan bir GIF dosyasını yakalayıp gönderebiliyor musunuz?
Mühendis Toast,

Ne yazık ki, bunu yapacak araçlarım yok (sadece işyerinde inşa zamanlarında uğraşırken) Doğru satır 0 ile güncelleyeceğim, ancak kolay bir düzeltme.
LambdaBeta

Geçersiz: yeni bir yay başlamadan önce (ilk yaydan önce isteğe bağlı) sadece temel bir merdivenin (
yaysız

k = 1 ila k = 0 arasında değişiklik yapılması ... 0 bayt maliyetini düzeltir. Yakında güncellenecek.
LambdaBeta

2

PowerShell , 347 319 bayt

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

Çevrimiçi deneyin! Alınamadı $argsbağlantı konsolu temizlemeden işlevini çağırır böylece, nice oynamak için.

Ungolfed

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

Bu küçük bir şey, ancak alt satırda makrolar yerine kısa çizgiler. Bu sıfır baytlık bir değişiklik$l=(($h..1)|%{"$(" "*($h-$_))\$(" "*$_*2)/"})+"$(" "*$h)¯¯"
Engineer Toast

1
¯ \ (° _o) / ¯ ayy! makrolarda değiştirildi: p
Peter Vandivier

1
PowerShell'i çok iyi tanımıyorum, ancak yeni satırların çoğunu kaldırabilirsiniz. Ek olarak for($x=0;$x-ne$n;$x++)olabilir for($x=0;$x++-ne$n;). Bunu 324 bayta (321 karakter) indirdim . İçinde golf için ipuçları <tüm diller> ve PowerShell içinde golf için ipuçları yanı okumaya ilginç olabilir.
Kevin Cruijssen

1
sleep 1biraz kaydeder (varsayılan değere-saniye), ancak oldukça yavaş ama yine de makul olan ish, sleep -m 99oldukça hızlı ama aynı zamanda makul. İstediğinize bağlı olarak 5/1 bayt kaydeder. Kevin'in girişimini kontrol değil mi functionüzere filterserbest bayt sıra olduğunu.
Veskah

1

Ruby , 293 bayt

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

Çevrimiçi deneyin!

Pencerelerdeyim, bu yüzden konsolu silmek için birçok "\ n" yazıyor. 2 argüman alır nve hstdin'de iki satır halinde.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.