看不到钥匙的森林


16

以任何合理的方便格式(例如4, 0, -1, -6, 2或)编写一个以非空整数列表形式接受的程序或函数[4 0 -1 -6 2]

打印或返回一个将列表描述为ASCII艺术林的字符串,其中每个数字都变成成比例高度的树。每棵树在输出中占据四列文本,如下所示:

  • 一个正整数N成为一棵树,其底为__|_,top为 ^ / \介于两者之间。

    例如,当N = 1时,树是

      ^
     / \
    __|_
    

    当N = 2时,树是

      ^
     / \
     / \
    __|_
    

    当N = 3时,树是

      ^
     / \
     / \
     / \
    __|_
    

    等等。

  • 负整数N就像相应的正树一样,只不过在分支斜杠之间有一个竖线而不是空格。

    例如,当N = -1时,树为

      ^
     /|\
    __|_
    

    当N = -2时,树为

      ^
     /|\
     /|\
    __|_
    

    当N = -3时,树为

      ^
     /|\
     /|\
     /|\
    __|_
    

    等等。

  • 当整数为0时,从技术上讲,没有树,只有四个下划线的空白:

    ____
    

每棵树的底部的下划线必须在输出中对齐,即所有树的底部必须在同一水平。此外,单个下划线将添加到最后一棵树之后的下划线行的末尾。这样一来,每棵树的两边都会有一个空的“空气”列。

作为一个示例,输出为4 0 -1 -6 2

              ^
             /|\
  ^          /|\
 / \         /|\
 / \         /|\  ^
 / \      ^  /|\ / \
 / \     /|\ /|\ / \
__|_______|___|___|__

请注意,树形图样始终总是有一个空白列,但必须添加下划线以填充最后一棵树的右侧。

也:

  • 任何行上的尾随空格都可以,但是不应有不必要的前导空格。
  • 不允许使用前导换行符(最高的树应触摸输出文本网格的顶部),并且最多只允许尾随一个换行符。
  • 该列表可以包含-250至250之间的任何整数。不需要处理高大的树木。

以字节为单位的最短代码获胜。

更多例子

3

  ^
 / \
 / \
 / \
__|__

-2

  ^
 /|\
 /|\
__|__

0

_____

0, 0

_________

0, 1, 0

      ^
     / \
______|______

0, -1, 2, -3, 4

                  ^
              ^  / \
          ^  /|\ / \
      ^  / \ /|\ / \
     /|\ / \ /|\ / \
______|___|___|___|__

Answers:


6

Pyth,48个字节

j_.t+sm.i,J\_?d++\|sm?>d0\ \|d\^Jms+Jmkd"/\\"QJd

在线尝试:演示测试套件

懒惰的完整解释。这里只是简短的概述:

我首先生成列。因此图像:

      ^ 
  ^  /|\
 / \ /|\
__|___|__

生成为:

["_", "_/", "| ^", "_\", "_", "_//", "|||^", "_\\", "_"]

注意,我只生成下部(所有不包含空格的部分)。我也在从下到上生成它们。这非常简单。

然后,我可以使用该.t方法在字符串后面添加空格,以便每个字符串具有相等的长度。然后我颠倒顺序并打印。


注意:如果这是实际输出,则可能忘记了_在最后一棵树后添加尾随(下划线)。
插入用户名

1
@insertusernamehere谢谢,完全忽略了结尾_
Jakube 2015年

7

Python 2,165字节

a=input()
l=max(map(abs,a))
while l+2:s=' _'[l<0];print(s+s.join((([' ^ ','//| \\\\'[x>0::2],'   '][cmp(abs(x),l)],'_|_')[l<0],s*3)[x==0]for x in a)+s).rstrip();l-=1

这是一个接受列表作为输入的完整程序。我仍然在打高尔夫球,这可怕的一团糟。


4

PHP,231277字节

这项挑战具有出色的成果。

$x=fgetcsv(STDIN);for(;$i<2+max(array_map(abs,$x));$i++)for($j=0;$j<count($x);){$_=$x[$j++];$o[$i].=!$i?$_?'__|_':____:(abs($_)>=$i?0>$_?' /|\\':' / \\':($i-1&&abs($_)==$i-1?'  ^ ':'    '));}echo implode("
",array_reverse($o))."_";

从读取一个逗号分隔的列表(空格是可选的)STDIN

$ php trees.php
> 1, 2, 0, -4, 6

不打高尔夫球

$x=fgetcsv(STDIN);
for(;$i<2+max(array_map(abs,$x));$i++)
    for($j=0;$j<count($x);){
        $_=$x[$j++];
        $o[$i] .= !$i ? $_?'__|_':____
                      : (abs($_)>=$i ? 0>$_?' /|\\':' / \\'
                                     : ($i-1&&abs($_)==$i-1 ? '  ^ ' : '    '));
    }
echo implode("\n",array_reverse($o))."_";

编辑

  • 保存了 46个字节。舍弃的数组初始化,if/else由三元运算符代替,并移动一些变量以节省一些字节。

2

Ruby,157156153 字符

->h{r=[]
h.map{|i|j=i.abs
r+=[s=?_,?/*j+s,i==0?s:?^+(i>0?' ':?|)*j+?|,?\\*j+s].map{|l|l.rjust(h.map(&:abs).max+2).chars}}
r.transpose.map{|l|l*''}*$/+?_}

仅仅因为最初Array.transpose看起来是个好主意而写。不再。

样品运行:

2.1.5 :001 > puts ->h{r=[];h.map{|i|j=i.abs;r+=[s=?_,?/*j+s,i==0?s:?^+(i>0?' ':?|)*j+?|,?\\*j+s].map{|l|l.rjust(h.map(&:abs).max+2).chars}};r.transpose.map{|l|l*''}*$/+?_}[[4, 0, -1, -6, 2]]
              ^     
             /|\    
  ^          /|\    
 / \         /|\    
 / \         /|\  ^ 
 / \      ^  /|\ / \
 / \     /|\ /|\ / \
__|_______|___|___|__

将片段收集到一个单独的数组中,而不是从第一个映射返回它们,应该可以避免使用reduce。
manatwork 2015年

0

C#,318个字节

我试过转置数组。我不确定这是否是最佳解决方案。

string F(int[]a){int i=a.Length,j,w=i*4+1,h=0;string f="",o=f;for(;i-->0;){j=a[i];f+=","+" _,".PadLeft(j=j>0?j+3:-j+3,'\\')+(j>3?"^"+"|_,".PadLeft(j,a[i]<0?'|':' '):"_,")+" _,_".PadLeft(j+1,'/');h=h<j?j:h;}f="_".PadLeft(h=h>3?h:2,'\n')+f;for(i+=h<3?1:0;++i<h;)for(j=w;j-->0;)o+=f.Split(',')[j].PadLeft(h)[i];return o;}

缩进和换行符:

string F(int[]a)
{
    int i=a.Length,
        j,
        w=i*4+1,
        h=0;
    string f="",o=f;
    for(;i-->0;){
        j=a[i];
        f+=","+" _,".PadLeft(j=j>0?j+3:-j+3,'\\')+(j>3?"^"+"|_,".PadLeft(j,a[i]<0?'|':' '):"_,")+" _,_".PadLeft(j+1,'/');
        h=h<j?j:h;
    }
    f="_".PadLeft(h=h>3?h:2,'\n')+f;
    for(i+=h<3?1:0;++i<h;)
        for(j=w;j-->0;)
            o+=f.Split(',')[j].PadLeft(h)[i];
    return o;
}
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.