Je ne vois pas la forêt pour les clés

16

Écrivez un programme ou une fonction qui accepte une liste non vide d'entiers dans un format pratique raisonnable tel que 4, 0, -1, -6, 2ou [4 0 -1 -6 2].

Imprimez ou renvoyez une chaîne qui représente la liste comme une forêt d'art ASCII où chaque nombre devient un arbre de hauteur proportionnelle. Chaque arborescence occupe quatre colonnes de texte dans la sortie comme suit:

  • Un entier positif N devient un arbre dont la base est __|_et le sommet est ^ , avec N couches d' / \entre les deux.

    Par exemple, lorsque N = 1, l'arbre est

      ^
     / \
    __|_
    

    lorsque N = 2, l'arbre est

      ^
     / \
     / \
    __|_
    

    lorsque N = 3, l'arbre est

      ^
     / \
     / \
     / \
    __|_
    

    etc.

  • Un entier négatif N devient exactement comme l'arbre positif correspondant, sauf qu'une barre verticale se trouve entre les barres obliques au lieu d'un espace.

    Par exemple, lorsque N = -1, l'arbre est

      ^
     /|\
    __|_
    

    lorsque N = -2, l'arbre est

      ^
     /|\
     /|\
    __|_
    

    lorsque N = -3, l'arbre est

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

    etc.

  • Lorsque l'entier est 0, il n'y a techniquement pas d'arbre, juste un espace vide de quatre traits de soulignement:

    ____
    

Les traits de soulignement à la base de chaque arbre doivent être alignés dans la sortie, c'est-à-dire que tous les arbres doivent avoir leurs bases au même niveau. En outre, un seul trait de soulignement est ajouté à la fin de la ligne de traits de soulignement après le dernier arbre. Cela fait en sorte que chaque arbre a une colonne vide "d'air" de chaque côté.

Par exemple, la sortie pour 4 0 -1 -6 2serait

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

Notez que les modèles d'arbre ont toujours une colonne principale d'espace vide mais un trait de soulignement a dû être ajouté pour remplir le côté droit du dernier arbre.

Aussi:

  • Les espaces de fin sur n'importe quelle ligne conviennent, mais il ne doit pas y avoir d'espaces de début inutiles.
  • Les sauts de ligne de début ne sont pas autorisés (l'arbre le plus haut doit toucher le haut de la grille de texte de sortie) et un seul saut de ligne de fin est autorisé.
  • La liste peut contenir tous les entiers de -250 à 250 inclus. Il n'est pas nécessaire de manipuler des arbres plus grands.

Le code le plus court en octets gagne.

Plus d'exemples

3:

  ^
 / \
 / \
 / \
__|__

-2:

  ^
 /|\
 /|\
__|__

0:

_____

0, 0:

_________

0, 1, 0:

      ^
     / \
______|______

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

                  ^
              ^  / \
          ^  /|\ / \
      ^  / \ /|\ / \
     /|\ / \ /|\ / \
______|___|___|___|__
Loisirs de Calvin
la source

Réponses:

6

Pyth, 48 octets

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

Essayez-le en ligne: démonstration ou suite de tests

Trop paresseux pour une explication complète. Voici un bref aperçu:

Je génère d'abord les colonnes. Donc l'image:

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

est généré comme:

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

Remarquez que je ne génère que la partie inférieure (tout sans les espaces). Et je les génère également de bas en haut. Cela se fait assez simplement.

Ensuite, je peux utiliser la .tméthode pour ajouter des espaces aux chaînes, de sorte que chaque chaîne ait une longueur égale. Et après, j'inverse la commande et j'imprime.

Jakube
la source
Remarque: s'il s'agit d'une sortie réelle, vous avez peut-être oublié d'ajouter une fin _(trait de soulignement) après la dernière arborescence.
insertusernamehere
1
@insertusernamehere Merci, complètement ignoré la fin _.
Jakube
7

Python 2, 165 octets

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

Il s'agit d'un programme complet qui accepte une liste en entrée. Je joue toujours à ce désordre horrible.

xsot
la source
4

PHP, 231 277 octets

Ce défi a une belle sortie.

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

Lit une liste séparée par des virgules (les espaces sont facultatifs) à partir de STDIN:

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

Non golfé

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

Modifications

  • Enregistré 46 octets . Initialisation du tableau ignorée, remplacée if/elsepar des opérateurs ternaires et déplacé certaines variables pour économiser quelques octets.
insertusernamehere
la source
2

Ruby, 157 156 153 caractères

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

Écrit juste parce qu'au départ, cela Array.transposesemblait être une bonne idée. Plus maintenant.

Exemple d'exécution:

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]]
              ^     
             /|\    
  ^          /|\    
 / \         /|\    
 / \         /|\  ^ 
 / \      ^  /|\ / \
 / \     /|\ /|\ / \
__|_______|___|___|__
homme au travail
la source
La collecte des pièces dans un tableau séparé au lieu de les renvoyer de la première carte devrait permettre d'éviter l'utilisation de réduire.
manatwork du
0

C #, 318 octets

J'ai essayé de transposer le tableau. Je ne sais pas si c'était la meilleure 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 et nouvelles lignes pour plus de clarté:

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
la source