动画Jacob的ASCII梯形图


23

您可能已经在儿童科学博物馆中看到了雅各的阶梯。如果您不熟悉它们的外观,那么Wikimedia Commons上有一些图像和视频示例。今天的挑战是创建电子设备的动画ASCII版本。最后,它应该看起来像这样:

梯子GIF示例


梯子构造

这是高度(H)为6 的梯子的基本形状:

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

左侧的数字仅表示此示例的行号,不应包含在输出中。我们将通过数字(R)引用给定的行。第0行是底部¯¯。从1到H的每一行包括四个部分:

  • 空格(U + 0020)重复(H - R)次
  • 反斜线\(U + 005C)
  • 空格(U + 0020)重复(2 * R)次
  • 正斜杠/(U + 002F)

第0行是相同的,除了两个斜杠都用宏¯(U + 00AF)代替。在每行末尾或梯形图下方都可以留有空白。前导空格不是。


电弧构造

构造好梯子后,即可在左侧和右侧之间创建圆弧。一个弧线完全位于一行内,并替换了前导\和尾随之间的空间/。因此,第2行的弧中将包含4个字符,第3行的弧中将包含6个字符,依此类推。每个弧均使用以下规则组成:

  • 唯一允许的字符是_/¯\(U + 005F,U + 002F,U + 00AF,U + 005C)
  • 为了确保外观平滑,请在¯/后面加上¯或。\
  • 为了确保外观平滑,请在_\后面加上_或。/
  • 上面的两个规则也适用于梯子的边缘
  • 这三个规则上面实际上意味着,在圆弧的第一个字符必须是_或者/最后一个字符必须是_\\¯\_//是两端无效,但\_/¯\/就是OK)
  • 每个允许的字符在给定的点上必须有一个非零的机会
  • 每个弧彼此独立

动画

通过从第1行开始并每次将其“移动”到上一行直到到达顶部,来创建单个电弧的寿命。IE,首先在第1行生成弧,然后将其设置回空格并在第2行生成弧,依此类推。给定多个要显示的弧(N),请遵循以下准则一次显示一个弧的完整寿命:

  • 任何时候都只有一个弧是“活动的”。下一条弧线无法开始,直到当前的弧线到达顶部然后熄灭为止。
  • 弧线寿命的每一行应精确显示一帧
  • 在新弧开始之前(仅在第一弧之前),应该只有一帧基本梯子(无弧)
  • 动画应显示N弧的整个寿命。如果N = 0,则应永久设置随机弧的动画,直到停止。
  • 如果N > 0,您可能仍会永远循环播放动画,但它必须是一遍又一遍相同弧线的循环。(这篇文章顶部的示例GIF具有H = 6和N = 3,但它会永远循环。)
  • 动画应在原地进行。也就是说,每个帧都应完全覆盖下一帧并位于同一位置。
  • 每帧的长度可以是您想要的任何长度,但可以使人观看(IE,使用您的常识:0.01s /帧和30s /帧都是不可接受的。)

输入输出

  • 输入和输出可以是任何标准格式
  • 您可以导出GIF,在屏幕上写文本,为每帧输出一个文件,或任何其他合理的方式
  • 禁止出现标准漏洞
  • 梯子H的高度将为正整数
  • 显示N的弧数将为非负整数
  • 无论^ hñ被视为任何你选择的顺序(请在你的答案的顺序)输入

获奖条件

这是因此最短的代码获胜。

沙盒


1
圆弧能否通过其中心对称地生成?我在规则中看不到对此的限制
Dead Possum

我可以将每帧打印到控制台吗?
TF场,2018年

@DeadPossum我想你是对的,尽管事实上它也不会显得很雷-Y,但它实际上是由两个规则的组合不允许:the first character in the arc must be _ or / and the last character must be _ or \ There must be a non-zero chance for each allowable character to occur at a given point。为了对称,第一个字符和最后一个字符都必须_每次都出现一次,这意味着出现/或出现\的可能性为零。
工程师吐司

@TFeld只要每个帧出现在屏幕上的相同位置,就可以。这意味着您每次都必须清除控制台(或者,如果可能的话,可以向下滚动)。
工程师吐司

2
宏要求是否意味着QBasic无法竞争?它使用CP437,其代码点0xAF»
DLosc

Answers:


5

Python 2中287 271 270 276 275字节

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)

在线尝试!

无法清除tio上的屏幕,但可以在控制台中使用。

它运行的Gif:

在此处输入图片说明


有点偷偷摸摸,但您可以使用print'\n'*99代替os.system('cls')并丢失os导入。仍然不能在TIO上运行,但可以在Windows和Linux控制台上运行。
ElPedro

1
在新弧开始之前(仅在第一弧之前),应该[只有]一帧基本梯子(无弧)
wastl

5
我认为您使用的是连字符(U + 002D)而不是宏子(U + 00AF)。我认为它不会增加字节数来解决它。另外,正如@wastl所指出的,弧之间没有空梯子框架。
Engineer Toast

最下面一行使用宏子,但是弧不使用
Engineer Toast

1
@EngineerToast已修复:)
TFeld

4

JavaScript(ES6),245个字节

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>

字节数假定为ISO-8859-1编码。


通过A=x=>[...Array(x)].map;在开始时定义并替换两种用法,可以将其减少到242 。
Bary12 '18

@ Bary12您不能返回map,这仅是的属性,不能单独Array.prototype使用。我尝试了工作版本,但它们全部都超过了245个字节。
尼尔

3

C(gcc),406字节

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

在线尝试!

描述:

#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

注意:仅在Xterm中才有效...许多终端仿真器仅不支持保存/恢复位置。
LambdaBeta

最底行是第0行,只有两个宏。不是\--/。这可能很容易解决。您是否可以在Xterm中捕获并发布GIF的GIF?
Engineer Toast

可悲的是,我缺乏做到这一点的工具(只是在工作的构建时间内玩耍)。我将使用正确的第0行进行更新,这很容易解决。
LambdaBeta

无效:在新弧开始之前(仅在第一弧之前),应该[只有]一帧基本阶梯(无弧)
wastl

将k = 1更改为k = 0可以解决... 0字节开销。即将更新。
LambdaBeta

2

电源外壳347319字节

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

在线尝试!无法正常$args播放,因此该链接会在不清除控制台的情况下调用该函数。

不打高尔夫球

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

这是一件小事,但最下面一行是连字符而不是宏子。这是一个零字节的更改$l=(($h..1)|%{"$(" "*($h-$_))\$(" "*$_*2)/"})+"$(" "*$h)¯¯"
Engineer Toast

1
¯\(°_o)/¯糟糕!换成Macrons:p
Peter Vandivier

1
我不太了解PowerShell,但是您可以删除大多数换行符。另外for($x=0;$x-ne$n;$x++)可以for($x=0;$x++-ne$n;)。我这样做可以减少到324字节(321个字符)阅读所有语言的打高尔夫球技巧PowerShell中打高尔夫球的技巧可能也很有趣。
凯文·克鲁伊森

1
sleep 1节省了一点时间(默认为-seconds),但速度很慢,但仍然很合理,sleep -m 99相当快但也很合理。根据您的喜好保存5/1个字节。没有检查Kevin的尝试,但是functionto filter也是一个空闲字节。
Veskah

1

红宝石,293字节

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

在线尝试!

我在Windows上,因此它只打印许多“ \ n”以清除控制台。接受2个参数,nh作为stdin的两行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.