| Bytes | Lang | Time | Link |
|---|---|---|---|
| 149 | JavaScript V8 | 241211T194004Z | Weird Gl |
| 213 | JavaScript V8 | 241210T073023Z | thejonym |
| 126 | Perl 5 MListUtil=max a | 241210T210400Z | Xcali |
| 258 | Setanta | 241210T081311Z | bb94 |
| 041 | Canvas | 210207T113354Z | Razetime |
| 167 | PowerShell | 200228T103527Z | mazzy |
| 318 | C# | 151217T123440Z | Hand-E-F |
| 153 | Ruby | 151208T172258Z | manatwor |
| 231 | PHP | 151207T225519Z | insertus |
| 048 | Pyth | 151207T200005Z | Jakube |
| 165 | Python 2 | 151207T060316Z | xsot |
JavaScript (V8), 157 156 154 153 149 bytes
f=(l,i=Math.max(...m=l.map(Math.abs)))=>m.map((j,J)=>~i?i<j?l[J]<0?" /|\\":" / \\":!j|i>j?" ":" ^ ":j?"__|_":"____").join``+(~i?`
`+f(l,i-1):"_")
-1 byte thanks to emanresu A
Hello! First time posting here, I wanted to try to solve this problem as my first challenge, I saw that thejonymyster also answered it, but I was pretty happy with the answer I found, so I hope that I'm following the rules in this situation. Anyway, here's a prettier version of the code, mostly using a lot of ternaries and some recursion:
/* Line 1 ^ i: index of the line from the maximum absolute value to -1
Line 0 / \ j: absolute value of each element
Line -1 _|_ l[J]: non-absolute value (retrieved using the index) */
f=(l, i=Math.max(...m=l.map(Math.abs))) =>
m.map((j, J) =>
~i ? i<j ?
l[J]<0 ? " /|\\" : " / \\" :
!j | i>j ?
" " : " ^ "
: j ? "__|_" : "____"
).join``+(~i ? `
`+f(l,i-1) : "_") // empty line
JavaScript (V8), 213 bytes
x=>{a=Math;b=a.abs;c=a.sign;e=x.map(b);d=a.max(...e)+1;f="";while(d--){e.map((g,h)=>f+=[" ",` ${c(g)?"^":" "} `,` /${1+c(x[h])?" ":"|"}\\`][1+c(g-d)]);f+="\n"}return f+`_${x.map(i=>i?"_|_":"___").join("_")}_`}
Seems like the same as the other non-transposing answers, not all too many strategies to solve this. Transposing is probably shorter in js but I like this method better.
Perl 5 -MList::Util=max -a, 126 bytes
//&say map" ^ "x($_&&$'==-abs)||($_<0?' /|\\':' / \\')x($'>-abs)||$"x4,@F for-(max map{abs}@F)..0;say'_',map$_?"_|__":____,@F
Setanta, 258 bytes
gniomh(l){s:=""h:=0f:=fad@l D:=dearbh@mata le i idir(0,f)h=uas(h,D(l[i]))ma h{le j idir(h,-1){s+=" "le i idir(0,f)s+=[" "," ^ ",["/ \\","/|\\"][l[i]<0|0&1]][l[i]&uas(0,ios(2,1+D(l[i])-j))]s+="\n"}}s+="_"le i idir(0,f)s+=["___","_|_"][l[i]|0&1]toradh s+"_"}
PowerShell, 167 bytes
$h=(($r=($args|%{$a,$x=$_,-$_-ge0
'_';'_'+'/'*$a;'|_'[!$_]+(' ','|')[$_-lt0]*$a+'^'*!!$_
'_'+'\'*$a})+'_')|% Le*|sort)[-1]
$z=$r|% *ht $h;--$h..0|%{-join($z|% Ch* $_)}
Explanation:
Unrolled:
# a rotated forest with underscore after the last tree
$rotatedForest=$args|%{
$abs,$x=$_,-$_-ge0
'_'
'_'+'/'*$abs
'|_'[!$_]+(' ','|')[$_-lt0]*$abs+'^'*!!$_
'_'+'\'*$abs
}
$rotatedForest += '_'
# calc height
$height = ($rotatedForest|% Length|sort)[-1]
# PadRight all trees
$z = $rotatedForest|% PadRight $height
# Rotate -90
--$height..0|%{
-join($z|% Chars $_)
}
C#, 318 bytes
I tried transposing the array. I'm not sure if that was the best solution.
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;}
Indentation and newlines for clarity:
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;
}
Ruby, 157 156 153 characters
->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*''}*$/+?_}
Written just because initially Array.transpose looked like a good idea. Not anymore.
Sample run:
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]]
^
/|\
^ /|\
/ \ /|\
/ \ /|\ ^
/ \ ^ /|\ / \
/ \ /|\ /|\ / \
__|_______|___|___|__
PHP, 231 277 bytes
This challenge has a beautiful output.
$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))."_";
Reads a comma separated list (whitespaces are optional) from STDIN:
$ php trees.php
> 1, 2, 0, -4, 6
Ungolfed
$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))."_";
Edits
- Saved 46 bytes. Discarded array initialization, replaced
if/elsewith ternary operators and moved some of the variables around to save a few bytes.
Pyth, 48 bytes
j_.t+sm.i,J\_?d++\|sm?>d0\ \|d\^Jms+Jmkd"/\\"QJd
Try it online: Demonstration or Test Suite
Too lazy for a full explanation. Here just short overview:
I generate the columns first. So the image:
^
^ /|\
/ \ /|\
__|___|__
gets generated as:
["_", "_/", "| ^", "_\", "_", "_//", "|||^", "_\\", "_"]
Notice, that I'm generating only the lower part (everything without the spaces). And I'm also generating them from bottom to top. This is done pretty straightforward.
Then I can use the .t method to append spaces to the strings, so that each string has an equal length. And afterwards I reverse the order and print.
Python 2, 165 bytes
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
This is a full program that accepts a list as input. I'm still golfing this horrid mess.
