Visualisez un tableau

26

Étant donné un tableau de n'importe quelle profondeur, dessinez son contenu avec des bordures +-|autour de chaque sous- tableau . Ce sont les caractères ASCII pour les tuyaux plus, moins et verticaux.

Par exemple, si le tableau est [1, 2, 3], dessinez

+-----+
|1 2 3|
+-----+

Pour un tableau imbriqué tel que [[1, 2, 3], [4, 5], [6, 7, 8]], dessinez

+-----------------+
|+-----+---+-----+|
||1 2 3|4 5|6 7 8||
|+-----+---+-----+|
+-----------------+

Pour un tableau irrégulier tel que [[[1, 2, 3], [4, 5]], [6, 7, 8]], dessinez

+-------------------+
|+-----------+-----+|
||+-----+---+|6 7 8||
|||1 2 3|4 5||     ||
||+-----+---+|     ||
|+-----------+-----+|
+-------------------+

Notez qu'il y a plus d'espace après le dessin [6, 7, 8]. Vous pouvez soit dessiner le contenu sur la ligne supérieure, centrale ou inférieure, mais selon votre choix, vous devez rester cohérent.

Ce défi a été inspiré par le verbe boîte< de J.

Règles

  • C'est le donc le code le plus court l'emporte.
  • Les buildins qui résolvent ce problème ne sont pas autorisés.
  • Le tableau d'entrée ne contiendra que des valeurs entières non négatives ou des tableaux. Chaque tableau sera homogène, ce qui signifie que ses éléments seront soit uniquement des tableaux ou uniquement des entiers, mais jamais un mélange des deux.
  • Chaque sous-réseau peut être imbriqué à n'importe quelle profondeur.
  • La sortie peut être soit sous forme de chaîne, soit sous forme de tableau de chaînes, chaque chaîne étant une ligne de sortie.

Cas de test

[]
++
||
++

[[], []]
+---+
|+++|
|||||
|+++|
+---+

[[], [1], [], [2], [], [3], []]
+-----------+
|++-++-++-++|
|||1||2||3|||
|++-++-++-++|
+-----------+

[[[[[0]]]]]
+---------+
|+-------+|
||+-----+||
|||+---+|||
||||+-+||||
|||||0|||||
||||+-+||||
|||+---+|||
||+-----+||
|+-------+|
+---------+

[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]
+---------------------------------+
|+-------------+---------+-----+-+|
||+-----------+|+-------+|+---+|1||
|||+---------+|||+-----+|||2 1|| ||
||||+-------+|||||3 2 1|||+---+| ||
|||||4 3 2 1|||||+-----+||     | ||
||||+-------+|||+-------+|     | ||
|||+---------+||         |     | ||
||+-----------+|         |     | ||
|+-------------+---------+-----+-+|
+---------------------------------+
miles
la source
Si ma langue n'a pas de tableaux imbriqués, puis-je ignorer la définition du type de données?
ThreeFx
1
@ThreeFx Vous pouvez également prendre l'entrée sous la forme d'une chaîne représentant le tableau imbriqué
miles
C'est VRAIMENT inefficace (à Haskell). Je devrais analyser les nombres manuellement et ainsi de suite. Dans ce cas, il serait plus court de définir et d'utiliser le type de données.
ThreeFx
@ThreeFx Ou vous pouvez remplir le tableau avec des valeurs sentinelles, car -1comme j'ai également limité les entiers à être non négatifs. Il suffirait alors de nettoyer la sortie pour ces valeurs non valides.
miles
1
@MitchSchwartz Bien sûr, prenez l'entrée dans un tuple imbriqué ou dans un format natif de votre langue. Votre sortie est correcte tant que vous restez cohérent. Les entiers peuvent être dessinés en haut, au centre ou en bas, et les boîtes peuvent être en haut, au centre, en bas ou étirées pour remplir leur espace comme dans votre exemple.
miles

Réponses:

4

Dyalog APL , 56 octets

Merci à ngn d'avoir aidé à supprimer environ un tiers des octets.

{⍵≡∊⍵:⍉⍪⍉⍕⍵⋄(⊢,⊣/)⊃,/(1⊖('++','|'⍴⍨≢),'-'⍪⍣2↑)¨↓↑↓¨∇¨⍵}⊂

TryAPL

Définissez la fonction , puis exécutez chaque scénario de test et comparez-le à l' ]Displayutilitaire intégré .
[1, 2, 3]
[[1, 2, 3], [4, 5], [6, 7, 8]]
[[[1, 2, 3], [4, 5]], [6, 7, 8]]
[]
[[], []]
[[], [1], [], [2], [], [3], []]
[[[[[0]]]]]
[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]

Explication

Dans l'ensemble, il s'agit d'une fonction anonyme {...}au sommet d'une enceinte . Ce dernier ajoute simplement un autre niveau d'imbrication invitant le premier à ajouter un cadre extérieur.

La fonction anonyme avec espace blanc ( est le séparateur d'instructions):

{
      ∊⍵:     
    (⊢ , ⊣/)  ,/ (1  ('++' , '|' ⍴⍨ ≢) , '-' ⍪⍣2 ↑)¨   ↓¨ ∇¨ 
}

Le voici à nouveau, mais avec des fonctions utilitaires séparées:

CloseBox   , ⊣/
CreateVertical  '++' , '|' ⍴⍨ 
AddHorizontals  1  CreateVertical , '-' ⍪⍣2 
{
      ∊⍵:     
    CloseBox  ,/ AddHorizontals¨   ↓¨ ∇¨ 
}

Maintenant, laissez-moi vous expliquer chaque fonction:

CloseBoxprend une table et renvoie la même table, mais avec la première colonne de la table ajoutée à droite de la table. Ainsi, étant donné le tableau 1 par 3 XYZ, cette fonction renvoie le tableau 1 par 4 XYZX, comme suit:
 l'argument (lit. ce qui est à droite) est
, ajouté à
⊣/ la colonne la plus à gauche (lit. la réduction gauche de chaque rangée)

CreateVerticalprend une table et renvoie la chaîne a composée des caractères qui correspondraient à |s sur les côtés de la table, mais avec deux +s ajoutés pour correspondre à deux lignes de -. Finalement, le tableau subira une rotation cyclique d'une ligne pour obtenir une seule +---...ligne au-dessus et en dessous. Ainsi, étant donné n'importe quelle table à trois lignes, cette fonction renvoie ++|||, comme suit:
'++' , deux points positifs ajoutés à
'|' ⍴⍨ un montant remodelé par
 le décompte (lignes ') de l'argument

AddHorizontalsprend une liste de listes, en fait un tableau, ajoute deux lignes de -s en haut, ajoute les caractères de bord gauche correspondants à gauche, puis fait pivoter une ligne vers le bas, de sorte que le tableau ait une bordure en haut , gauche et bas. Comme suit:
1 ⊖ faire pivoter une ligne (la ligne du haut va vers le bas) de
CreateVertical , la chaîne ++|||...ajoutée (en tant que colonne) au
'-' ⍪⍣2 moins ajouté deux fois en haut de
 l'argument transformé de liste de listes en table

{La fonction anonyme }: si l'argument est une liste simple (non imbriquée), transformez-la en une table de caractères (donc, étant donné la liste à 3 éléments 1 2 3, cette fonction renvoie la table de caractères 1 par cinq visuellement identique 1 2 3). Si l'argument n'est pas une simple liste, assurez-vous que les éléments sont de simples tables de caractères; les garnir à hauteur égale; encadrez chacun en haut, en bas et à gauche; les combiner; et enfin prendre la toute première colonne et l'ajouter à droite. Comme suit:
{ commencer la définition d'une fonction anonyme
  ⍵ ≡ ∊⍵:si l'argument est identique à l'argument aplati (c'est-à-dire qu'il s'agit d'une simple liste), puis:
    transposer l'  argument stratifié  transposé en
    colonnes ; else:  ajoutez la colonne la plus à gauche à droite de
   
   ⍕ ⍵
  CloseBox
  ⊃ ,/ les
  AddHorizontals¨ ajouts concaténés divulgués (car la réduction englobe) -en haut et en bas de chacun des
  ↓ ↑ ↓¨ rembourrés à hauteur égale * de
  ∇¨ ⍵  cette fonction anonyme appliquée à chacun des arguments mettent
} fin à la définition de la fonction anonyme
* Lit. faire de chaque table une liste de listes, combiner les listes de listes (remplissage avec des chaînes vides pour remplir des lignes courtes) en une table, puis diviser la table en une liste de listes de listes

Adam
la source
7

JavaScript (ES6), 223 203 octets

f=(a,g=a=>a[0].map?`<${a.map(g).join`|`}>`:a.join` `,s=g([a]),r=[s],t=s.replace(/<[ -9|]*>|[ -9]/g,s=>s[1]?s.replace(/./g,c=>c>`9`?`+`:`-`):` `))=>t<`+`?r.join`\n`.replace(/<|>/g,`|`):f(a,g,t,[t,...r,t])

Port de la solution Ruby de @ MitchSchwartz. Version précédente qui fonctionnait en encapsulant récursivement les tableaux (et fonctionnait donc pour du contenu arbitraire, pas seulement des entiers):

f=(...a)=>a[0]&&a[0].map?[s=`+${(a=a.map(a=>f(...a))).map(a=>a[0].replace(/./g,`-`)).join`+`}+`,...[...Array(Math.max(...a.map(a=>a.length)))].map((_,i)=>`|${a.map(a=>a[i]||a[0].replace(/./g,` `)).join`|`}|`),s]:[a.join` `]

Remarque: Bien que j'utilise l'opérateur d'étalement dans ma liste d'arguments, pour obtenir la sortie souhaitée, fournissez un seul paramètre du tableau d'origine plutôt que d'essayer de répartir le tableau; cela a pour effet d'envelopper la sortie dans la boîte extérieure souhaitée. Malheureusement, la boîte extérieure me coûte 18 octets, et la séparation de l'espace des entiers me coûte 8 octets, sinon la visualisation alternative suivante suffirait pour 197 octets:

f=a=>a.map?[s=`+${(a=a.map(f)).map(a=>a[0].replace(/./g,`-`)).join`+`}+`,...[...Array(Math.max(0,...a.map(a=>a.length)))].map((_,i)=>`|${a.map(a=>a[i]||a[0].replace(/./g,` `)).join`|`}|`),s]:[``+a]
Neil
la source
Est-ce que cela gère les tableaux vides? Je reçois une erreur Cannot read property 'map' of undefinedpour les tableaux vides tels que []. Pour [1,2,[]], le dernier sous-tableau ne s'affiche pas pour moi.
miles
@miles Désolé, j'avais oublié de vérifier les cas de test, et ceux-ci fonctionnent tous maintenant. Vous n'avez pas spécifié la sortie pour [1,2,[]]car vos exemples affichent uniquement des tableaux contenant des nombres entiers ou des tableaux, mais pas les deux.
Neil
Génial. N'oubliez pas non plus celui-là, je ne l'ai pas couvert dans les cas de test et le problème sera plus simple (car le vôtre est la seule entrée qui fonctionne jusqu'à présent) si chaque tableau est homogène.
miles
3

Rubis, 104 octets

->s{r=s=s.gsub'}{',?|
r=[s,r,s]*$/while s=s.tr('!-9',' ').gsub!(/{[ |]*}/){$&.tr' -}','-+'}
r.tr'{}',?|}

Fonction anonyme qui attend une chaîne. Par exemple, {{{{{4 3 2 1}}}}{{{3 2 1}}}{{2 1}}{1}}produit

+---------------------------------+
|+-------------+---------+-----+-+|
||+-----------+|         |     | ||
|||+---------+||+-------+|     | ||
||||+-------+||||+-----+||+---+| ||
|||||4 3 2 1||||||3 2 1||||2 1||1||
||||+-------+||||+-----+||+---+| ||
|||+---------+||+-------+|     | ||
||+-----------+|         |     | ||
|+-------------+---------+-----+-+|
+---------------------------------+

Vous pouvez utiliser ce code pour tester:

f=->s{r=s=s.gsub'}{',?|
r=[s,r,s]*$/while s=s.tr('!-9',' ').gsub!(/{[ |]*}/){$&.tr' -}','-+'}
r.tr'{}',?|}

a=[]

a<<'[1, 2, 3]'
a<<'[[1, 2, 3], [4, 5], [6, 7, 8]]'
a<<'[[[1, 2, 3], [4, 5]], [6, 7, 8]]'
a<<'[]'
a<<'[[], []]'
a<<'[[], [1], [], [2], [], [3], []]'
a<<'[[[[[0]]]]]'
a<<'[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]'

a.map{|s|s.gsub! '], [','}{'
s.tr! '[]','{}'
s.gsub! ',',''
puts s
puts f[s],''}

Cela commence à partir de la rangée du milieu et fonctionne vers l'extérieur. Tout d'abord, les instances de }{sont remplacées par |. Ensuite, alors qu'il y a encore des accolades, toutes les {...}chaînes les plus internes sont transformées en +-séquences appropriées tandis que les caractères autres que ceux-ci |{}sont transformés en espaces. À la fin, les entretoises intermédiaires sont transformées en tuyaux.

Mitch Schwartz
la source
J'ai pris quelques libertés avec les exigences de formatage d'entrée apparemment clémentes. Le code peut être facilement modifié pour gérer un format d'entrée différent, si nécessaire.
Mitch Schwartz
Recevoir des commentaires mal pensés est l'une des grandes joies de participer sur ce site.
Mitch Schwartz
3

Brainfuck, 423 octets

->>+>>,[[>+>+<<-]+++++[>--------<-]>[<+>-[[-]<-]]>[[-]<<[>>>>+<<<<<<-<[>-<-]>>>-
]<<<[-<<<<<<-<]>+>>>]<<<[>>+>>>>>+<<<<<<<-]>>>>>>>>>,]<<+[<<,++>[-[>++<,<+[--<<<
<<<<+]>]]<[-<+]->>>>[<++<<[>>>>>>>+<<<<<<<-]>>>-[<++>-[>>>>+<<<<<++<]<[<<]>]<[>>
+<<<<]>>>+>+>[<<<-<]<[<<]>>>>->+>[-[<-<-[-[<]<[<++<<]>]<[<++++<<]>]<[>+<-[.<<<,<
]<[<<]]>]<[-<<<<<]>>[-[<+>---[<<++>>+[--[-[<+++++++<++>>,]]]]]<+++[<+++++++++++>
-]<-.,>>]>>>>+>>>>]<<-]

Formaté avec quelques commentaires:

->>+>>,
[
  [>+>+<<-]
  +++++[>--------<-]
  >
  [
    not open paren
    <+>-
    [
      not paren
      [-]<-
    ]
  ]
  >
  [
    paren
    [-]
    <<
    [
      close paren
      >>>>+<<<<
      <<-<[>-<-]>>>
      -
    ]
    <<<
    [
      open paren directly after close paren
      -<<<<<<-<
    ]
    >+>>>
  ]
  <<<[>>+>>>>>+<<<<<<<-]>>>
  >>>>>>,
]
<<+
[
  <<,++>
  [
    -
    [
      >++<
      ,<+[--<<<<<<<+]
      >
    ]
  ]
  <[-<+]
  ->>>>
  [
    <++<<[>>>>>>>+<<<<<<<-]>>>-
    [
      at or before border
      <++>-
      [
        before border
        >>>>+<<<<
        <++<
      ]
      <[<<]
      >
    ]
    <
    [
      after border
      >>+<<
      <<
    ]
    >>>+>+>
    [
      column with digit or space
      <<<-<
    ]
    <[<<]
    >>>>->+>
    [
      middle or bottom
      -
      [
        bottom
        <-<-
        [
          at or before border
          -
          [
            before border
            <
          ]
          <
          [
            at border
            <++<<
          ]
          >
        ]
        <
        [
          after border
          <++++<<
        ]
        >
      ]
      <
      [
        middle
        >+<
        -[.<<<,<]
        <[<<]
      ]
      >
    ]
    <[-<<<<<]
    >>
    [
      border char or space
      -
      [
        not space
        <+>---
        [
          not plus
          <<++>>
          +
          [
            --
            [
              -
              [
                pipe
                <+++++++<++>>,
              ]
            ]
          ]
        ]
      ]
      <+++[<+++++++++++>-]<-.,>>
    ]
    > >>>+>>>>
  ]
  <<-
]

Essayez-le en ligne.

Attend une entrée formatée comme (((((4 3 2 1))))(((3 2 1)))((2 1))(1))avec un retour à la ligne de fin et produit une sortie du formulaire:

+---------------------------------+
|+-------------+---------+-----+-+|
||+-----------+|+-------+|+---+| ||
|||+---------+|||+-----+|||   || ||
||||+-------+|||||     ||||   || ||
|||||4 3 2 1||||||3 2 1||||2 1||1||
||||+-------+|||||     ||||   || ||
|||+---------+|||+-----+|||   || ||
||+-----------+|+-------+|+---+| ||
|+-------------+---------+-----+-+|
+---------------------------------+

L'idée de base est de calculer le caractère à imprimer en fonction de la profondeur d'imbrication. Le format de sortie est tel que l'index de ligne de la bordure supérieure d'une boîte est égal à la profondeur du tableau correspondant, avec une symétrie sur la ligne du milieu.

La bande est divisée en nœuds à 7 cellules, chaque nœud représentant une colonne dans la sortie.

La première boucle consomme l'entrée et initialise les nœuds, en gardant une trace de la profondeur et si la colonne correspond à une parenthèse (c'est-à-dire si la colonne contient une bordure verticale), et en réduisant les occurrences de )(en nœuds uniques.

La boucle suivante génère une ligne par itération. Dans cette boucle, une autre boucle traverse les nœuds et imprime un caractère par itération; c'est là que la plupart du travail a lieu.

Lors de la boucle d'initialisation, la disposition mémoire d'un nœud au début d'une itération est

x d 0 c 0 0 0

xest un indicateur booléen indiquant si le caractère précédent était une parenthèse fermante, dest la profondeur (plus un) et cest le caractère actuel.

Pendant la boucle d'impression des caractères, la disposition de la mémoire d'un nœud au début d'une itération est

0 0 d1 d2 c p y

d1indique la profondeur par rapport à l'indice de rang pour la moitié supérieure; d2est similaire à d1mais pour la moitié inférieure; cest le caractère d'entrée pour cette colonne si chiffre ou espace, sinon zéro; pindique la phase, c'est-à-dire la moitié supérieure, la moitié médiane ou la moitié inférieure; et yest un drapeau qui se propage de gauche à droite, en gardant une trace de si nous avons encore atteint la rangée du milieu. Notez que depuis ydevient zéro après le traitement d'un nœud, nous pouvons utiliser la ycellule du nœud précédent pour gagner plus d'espace de travail.

Cette configuration nous permet d'éviter de calculer explicitement la profondeur maximale pendant la phase d'initialisation; l' yindicateur est propagé en arrière pour mettre à jour les pcellules en conséquence.

Il y a une -1cellule à gauche des nœuds pour faciliter la navigation, et il y a une cellule à droite des nœuds qui permet de savoir si nous avons encore imprimé la dernière ligne.

Mitch Schwartz
la source
2

PHP + HTML, non concurrent ( 170 141 135 130 octets)

enregistré 29 octets inspiré par SteeveDroz

<?function p($a){foreach($a as$e)$r.=(is_array($e)?p($e):" $e");return"<b style='border:1px solid;float:left;margin:1px'>$r</b>";}

pas en compétition car ce n’est pas une sortie ascii et parce que je laisse le navigateur faire tout le travail intéressant

Titus
la source
1
Vous pouvez créer des <b>balises au lieu de <div>et vous n'avez pas besoin de spécifier la couleur du border. (Économie de 9 octets)
SteeveDroz
Vous n'avez pas besoin de mettre un <tag> du tout, affichez simplement la sortie en texte brut, ce qui économisera beaucoup d'octets (80 octets pour tout le code après la suppression du HTML)
ClementNerma
@SteeveDroz Avec <b>, je peux également supprimer l' white-spaceattribut, économisant encore 19 octets. génial! Et je peux remplacer paddingparmargin
Titus
2

JavaScript (ES6), 221

Une fonction non récursive renvoyant un tableau de chaînes (utilisant toujours une sous-fonction récursive à l'intérieur)

a=>[...(R=(a,l)=>a[r[l]='',0]&&a[0].map?'O'+a.map(v=>R(v,l+1))+'C':a.join` `)([a],l=-1,r=[],m='')].map(c=>r=r.map(x=>x+v[(k<0)*2+!k--],k=l,1/c?v='-- ':(v='-+|',c>'C'?k=++l:c>','&&--l,c='|'),m+=c))&&[...r,m,...r.reverse()]

Cela fonctionne en 2 étapes.

Étape 1: créez récursivement une représentation sous forme de chaîne du tableau d'entrée imbriqué. Exemple:

[[[1, 2, 3], [],[4, 5]], [6, 7, 8]] -> "OOO1 2 3,,4 5C,6 7 8CC"

Oet Cmarquez le sous-tableau ouvert et fermé. Les sous-tableaux numériques simples sont rendus avec les éléments séparés par un espace, tandis que si les membres du tableau sont des sous-tableaux, ils sont séparés par des virgules. Cette chaîne garde une trace de la structure à plusieurs niveaux du tableau d'entrée, tandis que je peux obtenir la ligne du milieu de la sortie en remplaçant simplement OC,par |. Lors de la construction récursive de cette chaîne temporaire, je trouve également le niveau de profondeur maximum et initialise un tableau de chaînes vides qui contiendra la moitié supérieure de la sortie.
Remarque: la boîte externe est délicate, j'imbrique l'entrée dans un autre tableau externe, puis j'ai supprimé la première ligne de sortie qui n'est pas nécessaire

Étape 2: scannez la chaîne temporaire et générez la sortie

Maintenant, j'ai un tableau de chaînes vides, une pour chaque niveau. Je scanne la chaîne de temp, en gardant une trace du niveau actuel, qui augmente pour chacun Oet diminue pour chacun C. Je visualise ceci comme ça:

[[[1, 2, 3], [],[4, 5]], [6, 7, 8]]

OOO1 2 3,,4 5C,6 7 8CC
+                    +
 +            +     +
  +     ++   +
|||1 2 3||4 5||6 7 8||

Le plus le monte et descend suit le niveau actuel

Pour chaque caractère, j'ajoute un caractère à chaque ligne de sortie, en suivant les règles:
- si chiffre ou espace, mettez un '-' au niveau actuel et en dessous, mettez un espace au dessus
- sinon, mettez un '+' au niveau actuel, mettez un «-» si ci-dessous et mettez un «|» si au-dessus

OOO1 2 3,,4 5C,6 7 8CC
+--------------------+
|+------------+-----+|
||+-----++---+|     ||
|||1 2 3||4 5||6 7 8||

Pendant le scan temporaire, je construis également la rangée du milieu en remplaçant OC,par|

À la fin de cette étape, j'ai la moitié supérieure et la rangée du milieu, je n'ai qu'à refléter le haut pour obtenir la moitié inférieure et j'ai terminé

Moins de golf, code commenté

a=>{
   r = []; // output array
   R = ( // recursive scan function
     a, // current subarray 
     l  // current level
   ) => (
     r[l] = '', // element of r at level r, init to ""
     a[0] && a[0].map // check if it is a flat (maybe empty) array or an array of arrays
     ? 'O'+a.map(v=>R(v,l+1))+'C' // mark Open and Close, recurse
     : a.join` ` // just put the elements space separated
   );
   T = R([a],-1)]; // build temp string
   // pass the input nested in another array 
   // and start with level -1 , so that the first row of r will not be visible to .map

   // prepare the final output
   m = '' // middle row, built upon the chars in T
   l = -1 // starting level
   [...T].map(c => // scan the temp string
         {
            k = l; // current level
            1/c // check if numeric or space
             ? v = '-- ' // use '-','-',' '
             : (
                 v = '-+|', // use '-','+','|'
                 c > 'C' 
                   ? k=++l // if c=='O', increment level and assign to k
                   : c>'A'&&--l, // if c=='C', decrement level (but k is not changed)
                 c='|' // any of O,C,comma must be mapped to '|'
               );
            m += c; // add to middle row
            r = r.map( (x,i) => // update each output row
                       // based on comparation between row index and level
                       // but in golfed code I don't use the i index
                       // and decrement l at each step  
                       x + v[(k<i)*2+!(k-i)]
                     )
         })
   // almost done!  
   return [...r,m,...r.reverse()]

)

Tester

F=
a=>[...(R=(a,l)=>a[r[l]='',0]&&a[0].map?'O'+a.map(v=>R(v,l+1))+'C':a.join` `)([a],l=-1,r=[],m='')].map(c=>r=r.map(x=>x+v[(k<0)*2+!k--],k=l,1/c?v='-- ':(v='-+|',c>'C'?k=++l:c>','&&--l,c='|'),m+=c))&&[...r,m,...r.reverse()]

out=x=>O.textContent = x+'\n'+O.textContent

;[[1,2,3]
,[[[1, 2, 3], [4, 5]], [6, 7, 8]]
,[]
,[[], []]
,[[], [1], [], [2], [], [3], []]
,[[[[[0]]]]]
,[[[[[4, 3, 2, 1]]]], [[[3, 2, 1]]], [[2, 1]], [1]]
].forEach(t=>
  out(JSON.stringify(t)+'\n'+F(t).join`\n`+'\n')
)  

function update()
{
  var i=eval(I.value)
  out(JSON.stringify(i)+'\n'+F(i).join`\n`+'\n')
}

update()
#I { width:90%}
<input id=I value='[[[1, 2, 3], [],[4, 5]], [6, 7, 8]]' oninput='update()'>
<pre id=O></pre>

edc65
la source
2

Rubis, 245 241 octets

Les frais généraux nécessaires pour tout emballer dans des boîtes ainsi que tout aligner sont assez lourds ...

Génère des tableaux de chaînes, avec une chaîne par ligne, conformément aux spécifications. Aligné en bas au lieu des exemples de cas de test alignés en haut car il enregistre 1 octet.

Essayez-le en ligne!

V=->a{a==[*a]?(k=a.map(&V);k[0]==[*k[0]]?[h=?++?-*((k.map!{|z|z[1,0]=[' '*~-z[0].size+?|]*(k.map(&:size).max-z.size);z};f=k.shift.zip(*k).map{|b|?|+b.reduce{|r,e|r+e[1..-1]}+?|})[0].size-2)+?+,*f,h]:[h="+#{?-*(f=k*' ').size}+",?|+f+?|,h]):a}
Encre de valeur
la source
@ Adám c'est résolu maintenant. Je ferai de mon mieux pour optimiser davantage plus tard ...
Value Ink
Nice.Première réponse avec alignement en bas. :-)
Adám
1

PHP, 404 octets

Toutes les solutions fonctionnent avec une profondeur maximale du tableau inférieure à 10. pour des valeurs supérieures, la profondeur doit être stockée dans un tableau et non dans une chaîne.

<?foreach(str_split(json_encode($_GET[a]))as$j){$j!="]"?:$c--;$r=($j==",")?($l=="]"?"":" "):$j;$r=$r=="]"?"|":$r;$r=$r=="["?($v=="]"?"":"|"):$r;if($r!=""){$n.=$r;$d.=+$c;}$v=$l;$l=$j;$j!="["?:$c++;$m>=$c?:$m=$c;}for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

Étendu

foreach(str_split(json_encode($_GET[a]))as$j){ # split JSON representation of the array
    $j!="]"?:$c--;
    $r=($j==",")?($l=="]"?"":" "):$j;
    $r=$r=="]"?"|":$r;
    $r=$r=="["?($v=="]"?"":"|"):$r;
    if($r!=""){
      $n.=$r;  # concanate middle string
      $d.=+$c; # concanate depth position
    }
    $v=$l;
    $l=$j;
    $j!="["?:$c++;
    $m>=$c?:$m=$c; # maximum depth of the array
}
for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)
$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));
# Build the strings before the middle string dependent of value middle string and depth 
echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z))); #Output

pour 425 octets, nous pouvons le faire avec REGEX

<?$n=($p=preg_filter)("#\]|\[#","|",$r=$p("#\],\[#","|",$p("#,(\d)#"," $1",json_encode($_GET[a]))));preg_match_all("#.#",$r,$e,256);foreach($e[0] as$f){$f[0]!="]"&&$f[0]!="|"?:$c--;$d.=+$c;$f[0]!="|"&&$f[0]!="["?:$c++;$m>=$c?:$m=$c;}for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

Étendu

$r=preg_filter("#\],\[#","|",preg_filter("#,(\d)#"," $1",json_encode($_GET[a])));
preg_match_all("#.#",$r,$e,256);
$n=preg_filter("#\]|\[#","|",$r); # concanate middle string
foreach($e[0] as$f){
    $f[0]!="]"&&$f[0]!="|"?:$c--;
    $d.=+$c; concanate depth position
    $f[0]!="|"&&$f[0]!="["?:$c++;
    $m>=$c?:$m=$c; # maximum depth of the array
}
# similar to the other ways
for($x=0;$x<strlen($n);$x++)
for($y=0;$y<$m;$y++)
$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));
echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

455 octets pour une solution récursive

<?function v($x,$t=0,$l=1){global$d;$d.=$t;$s="|";$c=count($x);foreach($x as$k=>$v){if(is_array($v))$e=v($v,$t+1,$k+1==$c);else{$e=$v." "[$k+1==$c];$d.=str_pad("",strlen($e),$t+1);}$s.=$e;}$d.=$l?$t:"";$s.=$l?"|":"";return$s;}$n=v($_GET[a]);$m=max(str_split($d));for($x=0;$x<strlen($n);$x++)for($y=0;$y<$m;$y++)$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));

Étendu

function v($x,$t=0,$l=1){
    global$d; # concanate depth position
    $d.=$t;
    $s="|";
    $c=count($x);
    foreach($x as$k=>$v){           
        if(is_array($v)){$e=v($v,$t+1,$k+1==$c);}
        else{$e=$v." "[$k+1==$c];$d.=str_pad("",strlen($e),$t+1);}
        $s.=$e;
    }
    $d.=$l?$t:"";
    $s.=$l?"|":"";
    return$s;
}
$n=v($_GET[a]); # concanate middle string
$m=max(str_split($d)); # maximum depth of the array
# similar to the other ways 
for($x=0;$x<strlen($n);$x++)
for($y=0;$y<$m;$y++)
$z[$y].=$y==$d[$x]&&$n[$x]=="|"?"+":($y<$d[$x]?"-":($y>$d[$x]&&$n[$x]=="|"?"|":" "));
echo join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));
Jörg Hülsermann
la source
1) $j!="]"?:$c--;-> $c-=$j=="]";(-2). 2) ($l=="]"?"":" ")-> " "[$l==$j](-5). Substitutions très probablement similaires dans la deuxième boucle. 3) if($r!=""){$n.=$r;$d.=+$c;}-> $n.=$r;if($r>"")$d.=+$c;(-3). 4) $l=$j;$j!="["?:$c++;-> $c+="["==$l=$j;(-5). 5) $x=0n'est pas nécessaire (-4). 6) for($y=0;$y<$m;$y++)-> for($y=$m;$y--;)(-4). 7) join("\n",$z),"\n$n\n".(join("\n",array_reverse($z)));-> join("\n",array_merge($z,[$n],array_reverse($z)));(-4) 8) espaces inutiles: foreach($e[0]as$f)(-1)
Titus
9) parenthèses inutiles en ($j==",")(-2). 10) if($r>"")$d.=+$c;-> $d.=$r>""?+$c:"";(-0)
Titus
version récursive: 1) $d.=$l?$t;est obsolète (-10) 2) $s.=$l?"|":"";return$s;-> return$s."|"[$l];(-6). 3) accolades obsolètes {$e=v($v,$t+1,$k+1==$c);}(-2). 4) {$e=$v." "[$k+1==$c];$d.=str_pad("",strlen($e),$t+1);}-> $d.=str_pad("",strlen($e=$v." "[$k+1==$c]),$t+1);(-5).
Titus