Nie widzę lasu dla kluczy

16

Napisz program lub funkcję, która przyjmuje niepustą listę liczb całkowitych w dowolnym rozsądnym dogodnym formacie, takim jak 4, 0, -1, -6, 2lub [4 0 -1 -6 2].

Wydrukuj lub zwróć ciąg przedstawiający listę jako las artystyczny ASCII, w którym każda liczba staje się drzewem o proporcjonalnej wysokości. Każde drzewo zajmuje cztery kolumny tekstu wyjściowego w następujący sposób:

  • Dodatnia liczba całkowita N staje się drzewem, którego podstawa jest __|_i góra jest ^ , z N warstwami / \pomiędzy nimi.

    Na przykład, gdy N = 1, drzewo jest

      ^
     / \
    __|_
    

    gdy N = 2, drzewo jest

      ^
     / \
     / \
    __|_
    

    gdy N = 3, drzewo jest

      ^
     / \
     / \
     / \
    __|_
    

    i tak dalej.

  • Ujemna liczba całkowita N staje się podobna do odpowiedniego drzewa dodatniego, z tym wyjątkiem, że pionowy pasek znajduje się między kreskami gałęzi zamiast spacji.

    Na przykład, gdy N = -1, drzewo jest

      ^
     /|\
    __|_
    

    gdy N = -2, drzewo jest

      ^
     /|\
     /|\
    __|_
    

    gdy N = -3, drzewo jest

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

    i tak dalej.

  • Kiedy liczba całkowita wynosi 0, technicznie nie ma drzewa, tylko pusta przestrzeń czterech znaków podkreślenia:

    ____
    

Podkreślenia u podstawy każdego drzewa muszą być wyrównane na wyjściu, tzn. Wszystkie drzewa muszą mieć swoje podstawy na tym samym poziomie. Ponadto pojedynczy znak podkreślenia jest dodawany na końcu wiersza podkreśleń po ostatnim drzewie. Dzięki temu każde drzewo ma po każdej stronie pustą kolumnę „powietrza”.

Przykładem 4 0 -1 -6 2może być wynik dla

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

Zwróć uwagę, że wzory drzew zawsze mają wiodącą kolumnę pustej przestrzeni, ale należało dodać podkreślenie, aby wstawić prawą stronę ostatniego drzewa.

Również:

  • Końcowe spacje na dowolnych liniach są w porządku, ale nie powinno być niepotrzebnych spacji wiodących.
  • Wiodące znaki nowej linii są niedozwolone (najwyższe drzewo powinno dotykać górnej krawędzi siatki tekstu wyjściowego) i dozwolony jest tylko jeden znak nowej linii.
  • Lista może zawierać dowolne liczby całkowite od -250 do 250 włącznie. Obsługa wyższych drzew nie jest wymagana.

Najkrótszy kod w bajtach wygrywa.

Więcej przykładów

3:

  ^
 / \
 / \
 / \
__|__

-2:

  ^
 /|\
 /|\
__|__

0:

_____

0, 0:

_________

0, 1, 0:

      ^
     / \
______|______

0, -1, 2, -3, 4:

                  ^
              ^  / \
          ^  /|\ / \
      ^  / \ /|\ / \
     /|\ / \ /|\ / \
______|___|___|___|__
Hobby Calvina
źródło

Odpowiedzi:

6

Pyth, 48 bajtów

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

Wypróbuj online: pakiet demonstracyjny lub testowy

Zbyt leniwy, by uzyskać pełne wyjaśnienie. Oto krótki przegląd:

Najpierw generuję kolumny. Obraz:

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

jest generowany jako:

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

Zauważ, że generuję tylko dolną część (wszystko bez spacji). Generuję je również od dołu do góry. Odbywa się to dość prosto.

Następnie mogę użyć .tmetody, aby dodać spacje do ciągów, aby każdy ciąg miał jednakową długość. A potem odwracam zamówienie i drukuję.

Jakube
źródło
Uwaga: jeśli jest to rzeczywisty wynik, być może zapomniałeś dodać końcowego _(podkreślenia) po ostatnim drzewie.
inserttusernamehere
1
@insertusernamehere Dzięki, całkowicie przeoczyłem końcowe _.
Jakube,
7

Python 2, 165 bajtów

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

Jest to pełny program, który przyjmuje listę jako dane wejściowe. Nadal gram w ten okropny bałagan.

xsot
źródło
4

PHP, 231 277 bajtów

To wyzwanie ma piękny efekt.

$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))."_";

Czyta listę oddzieloną przecinkami (białe znaki są opcjonalne) z STDIN:

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

Nie golfił

$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))."_";

Edycje

  • Zapisano 46 bajtów . Odrzucono inicjalizację tablicy, zastąpiono if/elseoperatorami trójskładnikowymi i przeniesiono niektóre zmienne, aby zaoszczędzić kilka bajtów.
wstawić nazwę tutaj
źródło
2

Ruby, 157 156 153 znaków

->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*''}*$/+?_}

Napisane tylko dlatego, że początkowo Array.transpose wyglądało na dobry pomysł. Nigdy więcej.

Przykładowy przebieg:

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]]
              ^     
             /|\    
  ^          /|\    
 / \         /|\    
 / \         /|\  ^ 
 / \      ^  /|\ / \
 / \     /|\ /|\ / \
__|_______|___|___|__
człowiek w pracy
źródło
Zebranie elementów do osobnej tablicy zamiast zwracania ich z pierwszej mapy powinno pozwolić na uniknięcie redukcji.
manatwork
0

C #, 318 bajtów

Próbowałem transponować tablicę. Nie jestem pewien, czy to było najlepsze rozwiązanie.

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

Wcięcia i nowe linie dla jasności:

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;
}
Hand-E-Food
źródło