Visualisieren Sie ein Array

26

Zeichnen Sie den Inhalt eines Arrays beliebiger Tiefe mit Rahmen +-|um jedes Subarray. Dies sind die ASCII-Zeichen für Plus, Minus und vertikale Pipe.

Wenn das Array beispielsweise ist [1, 2, 3], zeichnen Sie

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

[[1, 2, 3], [4, 5], [6, 7, 8]]Zeichnen Sie für ein verschachteltes Array wie

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

[[[1, 2, 3], [4, 5]], [6, 7, 8]]Zeichnen Sie für ein zerlumptes Array wie

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

Beachten Sie, dass nach dem Zeichnen mehr Platz vorhanden ist [6, 7, 8]. Sie können den Inhalt entweder in der obersten, in der Mitte oder in der untersten Zeile zeichnen, aber je nachdem, was Sie auswählen, müssen Sie konsistent bleiben.

Diese Herausforderung wurde durch das Box- Verb <von J. inspiriert.

Regeln

  • Das ist also gewinnt der kürzeste Code.
  • Builtins, die dies lösen, sind nicht erlaubt.
  • Das Eingabearray enthält nur nicht negative Ganzzahlwerte oder Arrays. Jedes Array ist homogen, dh, seine Elemente bestehen entweder nur aus Arrays oder nur aus ganzen Zahlen, jedoch niemals aus einer Mischung aus beiden.
  • Jedes Subarray kann bis zu einer beliebigen Tiefe verschachtelt sein.
  • Die Ausgabe kann entweder als Zeichenfolge oder als Array von Zeichenfolgen erfolgen, wobei jede Zeichenfolge eine Ausgabezeile ist.

Testfälle

[]
++
||
++

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

[[], [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|||||+-----+||     | ||
||||+-------+|||+-------+|     | ||
|||+---------+||         |     | ||
||+-----------+|         |     | ||
|+-------------+---------+-----+-+|
+---------------------------------+
Meilen
quelle
Kann ich die Definition des Datentyps ignorieren, wenn meine Sprache keine verschachtelten Arrays hat?
ThreeFx
1
@ThreeFx Sie können die Eingabe auch als Zeichenfolge verwenden, die das verschachtelte Array darstellt
Meilen
Das ist wirklich ineffizient (in Haskell). Ich müsste Zahlen manuell analysieren und so weiter. In diesem Fall wäre es kürzer, den Datentyp zu definieren und zu verwenden.
ThreeFx
@ThreeFx Oder Sie können das Array mit Sentinel-Werten auffüllen, z. B. -1weil ich auch die Ganzzahlen auf nicht negative Werte beschränkt habe. Dann müsste nur noch die Ausgabe für diese ungültigen Werte bereinigen.
Meilen
1
@MitchSchwartz Sicher, nehmen Sie die Eingabe in einem verschachtelten Tupel oder in einem Format, das Ihrer Sprache entspricht. Ihre Ausgabe ist in Ordnung, solange Sie konsistent bleiben. Ganzzahlen können oben, in der Mitte oder unten gezeichnet werden, und die Kästchen können oben, in der Mitte, unten oder gestreckt sein, um ihren Raum wie in Ihrem Beispiel auszufüllen.
Meilen

Antworten:

4

Dyalog APL , 56 Bytes

Vielen Dank an ngn für die Hilfe beim Entfernen von ungefähr einem Drittel der Bytes.

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

TryAPL

Definieren Sie die Funktion , führen Sie dann jeden Testfall aus und vergleichen Sie ihn mit dem integrierten ]DisplayDienstprogramm.
[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]]

Erläuterung

Insgesamt handelt es sich hierbei um eine anonyme Funktion {...}auf einem Gehäuse . Letzteres fügt lediglich eine weitere Verschachtelungsebene hinzu, die das erstere zum Hinzufügen eines äußeren Rahmens auffordert.

Die anonyme Funktion mit Leerzeichen ( ist das Anweisungstrennzeichen):

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

Hier ist es wieder, aber mit getrennten Hilfsfunktionen:

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

Lassen Sie mich nun jede Funktion erklären:

CloseBoxNimmt eine Tabelle und gibt dieselbe Tabelle zurück, wobei jedoch die erste Spalte der Tabelle rechts von der Tabelle angehängt wird. Ausgehend von der 1-mal-3-Tabelle XYZgibt diese Funktion die 1-mal-4-Tabelle zurückXYZX wie folgt zurück:
 Das Argument (lit. what is the right) steht vor der
, äußersten
⊣/ linken Spalte (lit. the left-reduction of each Reihe)

CreateVerticalNimmt eine Tabelle und gibt die a-Zeichenfolge zurück, die aus den Zeichen besteht, die |s an den Seiten der Tabelle entsprechen, wobei jedoch zwei +s vorangestellt werden, um zwei Zeilen von zu entsprechen -. Schließlich wird die Tabelle zyklisch um eine Zeile gedreht, um eine einzelne +---...Zeile darüber und darunter zu erhalten. Aus diesem Grund gibt diese Funktion bei einer Tabelle mit drei Zeilen ++|||Folgendes zurück:
'++' ,  Grund Zwei Pluszeichen vor
'|' ⍴⍨ einem Stil, der durch
 die (Zeilen-) Zählung des Arguments umgeformt wurde

AddHorizontalsNimmt eine Listenliste, erstellt eine Tabelle, fügt oben zwei Zeilen mit -s hinzu, fügt links die entsprechenden Zeichen am linken Rand hinzu und dreht dann eine Zeile nach unten, sodass die Tabelle oben einen Rand hat , links und unten. So
1 ⊖ drehen Sie eine Reihe (die obere Reihe geht nach unten)
CreateVertical , der Zeichenfolge ++|||... (als Spalte) vorangestellt ist, um das
'-' ⍪⍣2 Minus, das zweimal am Anfang des
 von der Liste der Listen in die Tabelle umgewandelten Arguments hinzugefügt wird

{Die anonyme Funktion }: Wenn das Argument eine einfache (nicht verschachtelte) Liste ist, machen Sie es zu einer Zeichentabelle (daher 1 2 3gibt diese Funktion bei einer Liste mit 3 Elementen die visuell identische 1 × 5-Zeichentabelle zurück 1 2 3). Wenn das Argument keine einfache Liste ist, stellen Sie sicher, dass die Elemente einfache Zeichentabellen sind. polstern sie auf gleiche Höhe; rahmen jeweils oben, unten und links ein; kombiniere sie; und schließlich nehmen Sie die allererste Spalte und fügen Sie es auf der rechten Seite. Wie folgt:
{ Beginnen Sie mit der Definition einer anonymen Funktion,
  ⍵ ≡ ∊⍵:wenn das Argument mit dem abgeflachten Argument identisch ist (dh es ist eine einfache Liste), und
    transponieren Sie die
    kolumnisierten einschließt
     transponiert
   ⍕ ⍵ Zeichenfolge Argument; sonst:
  CloseBox Fügen Sie die äußerste linke Spalte rechts von hinzu
  ⊃ ,/ Die offenbarten (weil die Reduktion einschließt) überlappenden
  AddHorizontals¨ Add- -s am oberen und unteren Rand jeder der auf * Lit. Machen Sie jede Tabelle zu einer Liste von Listen, kombinieren Sie die Listen von Listen (Auffüllen mit leeren Zeichenfolgen, um kurze Zeilen zu füllen) zu einer Tabelle und teilen Sie die Tabelle dann in eine Liste von Listen von Listen auf
  ↓ ↑ ↓¨ Die Auffüllung
  ∇¨ ⍵  dieser anonymen Funktion auf die gleiche Höhe *, die auf jedes Argument angewendet wird,
} beendet die Definition der anonymen Funktion

Adam
quelle
7

JavaScript (ES6), 223 203 Byte

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 von @ MitchSchwartz's Ruby-Lösung. Vorherige Version, in der die Arrays rekursiv umgebrochen wurden (und daher für beliebigen Inhalt und nicht nur für ganze Zahlen):

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` `]

Hinweis: Obwohl ich den Operator spread in meiner Argumentliste verwende, müssen Sie zur Erzielung der gewünschten Ausgabe einen einzelnen Parameter des ursprünglichen Arrays angeben, anstatt zu versuchen, das Array zu verbreiten. Dies hat den Effekt, dass die Ausgabe in die gewünschte äußere Box eingepackt wird. Leider kostet mich die äußere Box 18 Bytes, und das Trennen der ganzen Zahlen durch Leerzeichen kostet mich 8 Bytes, andernfalls würde die folgende alternative Visualisierung für 197 Bytes ausreichen:

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
quelle
Behandelt dies leere Arrays? Ich erhalte eine Fehlermeldung Cannot read property 'map' of undefinedfür leere Arrays wie []. Denn [1,2,[]]das letzte Subarray wird mir nicht angezeigt.
Meilen
@miles Sorry, ich hatte vergessen, die Testfälle zu überprüfen, und die funktionieren jetzt alle. Sie haben die Ausgabe für nicht angegeben, [1,2,[]]da in Ihren Beispielen nur Arrays angezeigt werden, die entweder Ganzzahlen oder Arrays enthalten, jedoch nicht beide.
Neil
Groß. Auch macht es nichts, ich habe es in den Testfällen nicht behandelt und das Problem wird einfacher (da Ihr Eintrag der einzige ist, der bisher funktioniert), wenn jedes Array homogen ist.
Meilen
3

Rubin, 104 Bytes

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

Anonyme Funktion, die eine Zeichenfolge erwartet. Zum Beispiel {{{{{4 3 2 1}}}}{{{3 2 1}}}{{2 1}}{1}}produziert

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

Sie können diesen Code zum Testen verwenden:

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],''}

Dies beginnt in der mittleren Reihe und funktioniert nach außen. Zunächst werden Instanzen von }{durch ersetzt |. Dann, während es noch geschweifte Klammern gibt, werden alle innersten {...}Zeichenfolgen in die entsprechenden +-Sequenzen umgewandelt, während andere Zeichen als |{}in Leerzeichen umgewandelt werden. Am Ende werden die Zwischenstreben zu Rohren.

Mitch Schwartz
quelle
Ich habe mir einige Freiheiten bei den scheinbar nachgiebigen Formatierungsanforderungen für die Eingabe genommen. Der Code kann bei Bedarf einfach geändert werden, um ein anderes Eingabeformat zu verarbeiten.
Mitch Schwartz
Schlecht durchdachte Kommentare zu erhalten, ist eine der großen Freuden, an dieser Site teilzunehmen.
Mitch Schwartz
3

Brainfuck, 423 Bytes

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

Mit einigen Kommentaren formatiert:

->>+>>,
[
  [>+>+<<-]
  +++++[>--------<-]
  >
  [
    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
                <+++++++<++>>,
              ]
            ]
          ]
        ]
      ]
      <+++[<+++++++++++>-]<-.,>>
    ]
    > >>>+>>>>
  ]
  <<-
]

Probieren Sie es online aus.

Erwartet eine Eingabe, die wie (((((4 3 2 1))))(((3 2 1)))((2 1))(1))eine nachgestellte Zeile formatiert ist , und gibt die folgende Form aus:

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

Die Grundidee ist die Berechnung des zu druckenden Zeichens anhand der Schachtelungstiefe. Das Ausgabeformat ist so, dass der Zeilenindex des oberen Rahmens einer Box der Tiefe des entsprechenden Arrays entspricht, wobei die Symmetrie über die mittlere Zeile verteilt ist.

Das Band ist in 7-Zellen-Knoten unterteilt, wobei jeder Knoten eine Spalte in der Ausgabe darstellt.

Die erste Schleife verwendet die Eingabe und initialisiert die Knoten, verfolgt dabei die Tiefe und ob die Spalte einer Klammer entspricht (dh ob die Spalte einen vertikalen Rand enthält) und reduziert Vorkommen von )( in einzelne Knoten.

Die nächste Schleife gibt eine Zeile pro Iteration aus. Innerhalb dieser Schleife durchläuft eine weitere Schleife die Knoten und gibt pro Iteration ein Zeichen aus. Hier findet die meiste Arbeit statt.

Während der Initialisierungsschleife ist das Speicherlayout eines Knotens am Anfang einer Iteration

x d 0 c 0 0 0

Dabei xist ein Boolesches Flag, das angibt, ob das vorherige Zeichen eine schließende Klammer war, ddie Tiefe (plus eins) und cdas aktuelle Zeichen.

Während der Zeichendruckschleife ist das Speicherlayout eines Knotens am Anfang einer Iteration

0 0 d1 d2 c p y

wo d1zeigt Tiefe verglichen mit Zeilenindex für die obere Hälfte; d2ist ähnlich, d1aber für die untere Hälfte; cist das Eingabezeichen für diese Spalte, wenn es sich um eine Ziffer oder ein Leerzeichen handelt, andernfalls Null; pgibt die Phase an, dh die obere Hälfte, die mittlere oder die untere Hälfte; undy ist eine Flagge, die sich von links nach rechts ausbreitet und verfolgt, ob wir die mittlere Reihe noch erreicht haben. Beachten Sie, dass ywir nach der Verarbeitung eines Knotens die yZelle des vorherigen Knotens verwenden können, um mehr Arbeitsraum zu gewinnen , da sie Null wird .

Mit diesem Setup können wir vermeiden, die maximale Tiefe während der Initialisierungsphase explizit zu berechnen. dasy Flag wird zurückpropagiert, um die pZellen entsprechend zu aktualisieren .

Es gibt eine -1Zelle auf der linken Seite der Knoten Navigation zu erleichtern, und es gibt eine Zelle rechts von Knoten , die Spur hält , ob wir die letzte Zeile gedruckt haben noch.

Mitch Schwartz
quelle
2

PHP + HTML, nicht konkurrierend ( 170 141 135 130 Bytes)

29 Bytes gespeichert, inspiriert von 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>";}

nicht konkurrieren, weil es keine ASCII-Ausgabe ist und weil ich den Browser die ganze interessante Arbeit machen lasse

Titus
quelle
1
Sie können <b>stattdessen Tags erstellen <div>und müssen die Farbe der nicht angeben border. (Sparen von 9 Bytes)
SteeveDroz
Sie brauchen überhaupt kein <tag> zu setzen, sondern zeigen nur die Ausgabe als Klartext an, wodurch eine Menge Bytes gespart werden (80 Bytes für den gesamten Code nach dem Entfernen von HTML)
ClementNerma
@SteeveDroz Mit <b>kann ich auch das white-spaceAttribut entfernen und weitere 19 Bytes sparen. toll! Und ich kann paddingmitmargin
Titus
2

JavaScript (ES6), 221

Eine nicht rekursive Funktion, die ein Array von Zeichenfolgen zurückgibt (in der immer noch eine rekursive Unterfunktion verwendet wird)

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()]

Dies funktioniert in 2 Schritten.

Schritt 1: Erstellen Sie rekursiv eine Zeichenfolgendarstellung des verschachtelten Eingabearrays. Beispiel:

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

Ound Cmarkiere open und close subarray. Einfache numerische Subarrays werden mit durch Leerzeichen getrennten Elementen gerendert, während Array-Mitglieder, wenn sie Subarrays sind, durch Kommas getrennt werden. Diese Saite hält die Multi - Level - Struktur des Eingangsfeldes verfolgen, während ich die mittlere Reihe des Ausgang nur ersetzt bekommen OC,mit |. Während ich diese temporäre Zeichenfolge rekursiv aufbaue, finde ich auch die maximale Tiefenebene und initialisiere ein Array von leeren Zeichenfolgen, die den halben oberen Teil der Ausgabe enthalten.
Hinweis: Die äußere Box ist schwierig. Ich verschachtele die Eingabe in einem anderen äußeren Array und lasse dann die erste Zeile der Ausgabe fallen, die nicht benötigt wird

Schritt 2: Scannen Sie die temporäre Zeichenfolge und erstellen Sie die Ausgabe

Jetzt habe ich eine Reihe von leeren Zeichenfolgen, eine für jede Ebene. Ich scanne die temporäre Zeichenfolge und verfolge den aktuellen Pegel, der für jede Zeichenfolge zunimmt Ound für jede Zeichenfolge abnimmt C. Ich visualisiere das so:

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

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

Das Pluszeichen für Auf und Ab folgt dem aktuellen Pegel

Für jedes Zeichen füge ich jeder Ausgabezeile ein Zeichen hinzu, wobei ich die folgenden Regeln befolge:
- Wenn Ziffer oder Leerzeichen, setze ein '-' auf die aktuelle Ebene und darunter, setze ein Leerzeichen darüber,
andernfalls ein '+' auf das aktuelles Level, setze ein '-' wenn darunter und setze ein '|' wenn oben

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

Während des temporären Scans baue ich auch die mittlere Zeile, die OC,durch ersetzt wird|

Am Ende dieses Schritts habe ich die obere Hälfte und die mittlere Reihe, ich muss nur die obere spiegeln, um die untere Hälfte zu erhalten, und ich bin fertig

Weniger Golf, kommentierter Code

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()]

)

Prüfung

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
quelle
2

Ruby, 245 241 Bytes

Der Overhead, der benötigt wird, um alles in Kisten zu wickeln und auszurichten, ist ziemlich schwer ...

Gibt Zeichenfolgenarrays mit einer Zeichenfolge pro Zeile gemäß der Spezifikation aus. Unten ausgerichtet anstelle der oben ausgerichteten Beispieltestfälle, da 1 Byte eingespart wird.

Probieren Sie es online!

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}
Wert Tinte
quelle
@Adám es ist jetzt behoben. Ich werde mein Bestes versuchen, um später weiter zu optimieren ...
Value Ink
Nice.First Antwort mit Ausrichtung von unten. :-)
Adám
1

PHP, 404 Bytes

Alle Lösungen arbeiten mit einer maximalen Tiefe des Arrays von weniger als 10. Für größere Werte muss die Tiefe in einem Array und nicht in einer Zeichenfolge gespeichert werden.

<?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)));

Erweitert

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

für 425 Bytes können wir das mit REGEX machen

<?$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)));

Erweitert

$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 Bytes für eine rekursive Lösung

<?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)));

Erweitert

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
quelle
1) $j!="]"?:$c--;-> $c-=$j=="]";(-2). 2) ($l=="]"?"":" ")-> " "[$l==$j](-5). Höchstwahrscheinlich ähnliche Substitutionen in der zweiten Schleife. 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=0wird nicht benötigt (-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) unnötiges Leerzeichen: foreach($e[0]as$f)(-1)
Titus
9) unnötige Klammern bei ($j==",")(-2). 10) if($r>"")$d.=+$c;-> $d.=$r>""?+$c:"";(-0)
Titus
rekursive Version: 1) $d.=$l?$t;ist veraltet (-10) 2) $s.=$l?"|":"";return$s;-> return$s."|"[$l];(-6). 3) veraltete Klammern {$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