Non riesco a vedere la foresta per le chiavi


16

Scrivi un programma o una funzione che includa un elenco non vuoto di numeri interi in qualsiasi formato conveniente ragionevole come 4, 0, -1, -6, 2o [4 0 -1 -6 2].

Stampa o restituisci una stringa che raffigura l'elenco come una foresta di arte ASCII in cui ogni numero diventa un albero di altezza proporzionale. Ogni albero occupa quattro colonne di testo nell'output come segue:

  • Un numero intero positivo N diventa un albero la cui base è __|_e la parte superiore è ^ , con N strati di / \in mezzo.

    Ad esempio, quando N = 1 l'albero è

      ^
     / \
    __|_
    

    quando N = 2 l'albero è

      ^
     / \
     / \
    __|_
    

    quando N = 3 l'albero è

      ^
     / \
     / \
     / \
    __|_
    

    e così via.

  • Un numero intero negativo N diventa esattamente come l'albero positivo corrispondente, tranne per il fatto che una barra verticale si trova tra le barre del ramo anziché uno spazio.

    Ad esempio, quando N = -1 l'albero è

      ^
     /|\
    __|_
    

    quando N = -2 l'albero è

      ^
     /|\
     /|\
    __|_
    

    quando N = -3 l'albero è

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

    e così via.

  • Quando il numero intero è 0 non c'è tecnicamente albero, solo uno spazio vuoto di quattro trattini bassi:

    ____
    

I caratteri di sottolineatura alla base di ciascun albero devono allinearsi nell'output, ovvero tutti gli alberi devono avere le loro basi allo stesso livello. Inoltre, un singolo carattere di sottolineatura viene aggiunto alla fine della linea di trattini bassi dopo l'ultimo albero. Questo lo rende così ogni albero ha una colonna vuota di "aria" su entrambi i lati di esso.

Ad esempio, l'output per 4 0 -1 -6 2sarebbe

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

Nota come i motivi ad albero abbiano sempre una colonna principale di spazio vuoto, ma è necessario aggiungere un carattere di sottolineatura per riempire il lato destro dell'ultimo albero.

Anche:

  • Gli spazi finali su qualsiasi linea vanno bene, ma non dovrebbero esserci spazi iniziali non necessari.
  • Non sono consentite nuove righe principali (l'albero più alto deve toccare la parte superiore della griglia del testo di output) e è consentita solo una nuova riga finale.
  • L'elenco può contenere numeri interi compresi tra -250 e 250 inclusi. Non è necessario maneggiare alberi più alti.

Vince il codice più breve in byte.

Altri esempi

3:

  ^
 / \
 / \
 / \
__|__

-2:

  ^
 /|\
 /|\
__|__

0:

_____

0, 0:

_________

0, 1, 0:

      ^
     / \
______|______

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

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

Risposte:


6

Pyth, 48 byte

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

Provalo online: dimostrazione o suite di test

Troppo pigro per una spiegazione completa. Ecco una breve panoramica:

Generare prima le colonne. Quindi l'immagine:

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

viene generato come:

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

Si noti che sto generando solo la parte inferiore (tutto senza gli spazi). E li sto anche generando dal basso verso l'alto. Questo è fatto abbastanza semplice.

Quindi posso usare il .tmetodo per aggiungere spazi alle stringhe, in modo che ogni stringa abbia una lunghezza uguale. E successivamente invertisco l'ordine e stampo.


Nota: se si tratta di un output effettivo, potresti aver dimenticato di aggiungere un finale _(carattere di sottolineatura) dopo l'ultimo albero.
inserireusernamehere

1
@insertusernamehere Grazie, completamente trascurato il finale _.
Jakube,

7

Python 2, 165 byte

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

Questo è un programma completo che accetta un elenco come input. Sto ancora giocando a golf questo orribile casino.


4

PHP, 231 277 byte

Questa sfida ha un bel risultato.

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

Legge un elenco separato da virgole (gli spazi bianchi sono facoltativi) da 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))."_";

Le modifiche

  • Salvato 46 byte . Inizializzazione dell'array scartata, sostituita if/elsecon operatori ternari e spostata alcune delle variabili per salvare alcuni byte.

2

Rubino, 157 156 153 caratteri

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

Scritto solo perché inizialmente Array.transposesembrava una buona idea. Non più.

Esecuzione di esempio:

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]]
              ^     
             /|\    
  ^          /|\    
 / \         /|\    
 / \         /|\  ^ 
 / \      ^  /|\ / \
 / \     /|\ /|\ / \
__|_______|___|___|__

Raccogliere i pezzi in un array separato invece di restituirli dalla prima mappa dovrebbe consentire di evitare l'uso di ridurre.
arte

0

C #, 318 byte

Ho provato a trasporre l'array. Non sono sicuro che fosse la soluzione migliore.

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

Rientro e newline per chiarezza:

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.