Wizualizuj tablicę

26

Biorąc pod uwagę tablicę o dowolnej głębokości, narysuj jej zawartość obramowaniami +-|wokół każdej podtablicy. Są to znaki ASCII dla potoku plus, minus i potoku pionowego.

Na przykład, jeśli tablica jest [1, 2, 3], narysuj

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

W przypadku zagnieżdżonej tablicy, takiej jak [[1, 2, 3], [4, 5], [6, 7, 8]]rysuj

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

W przypadku nierównej tablicy, takiej jak [[[1, 2, 3], [4, 5]], [6, 7, 8]]remis

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

Zauważ, że po rysowaniu jest więcej miejsca [6, 7, 8]. Możesz narysować zawartość na najwyższej, środkowej lub najniższej linii, ale cokolwiek wybierzesz, musisz zachować spójność.

To wyzwanie zostało zainspirowane czasownikiem pudełkowym< J.

Zasady

  • To jest więc wygrywa najkrótszy kod.
  • Wbudowane rozwiązania tego problemu są niedozwolone.
  • Tablica wejściowa będzie zawierać tylko nieujemne wartości całkowite lub tablice. Każda tablica będzie jednorodna, co oznacza, że ​​jej elementy będą albo tylko tablicami, albo tylko liczbami całkowitymi, ale nigdy nie będą mieszanką obu.
  • Każda podtablica może być zagnieżdżona na dowolnej głębokości.
  • Dane wyjściowe mogą być albo jako ciąg, albo jako tablica ciągów, gdzie każdy ciąg jest linią wyjściową.

Przypadki testowe

[]
++
||
++

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

[[], [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|||||+-----+||     | ||
||||+-------+|||+-------+|     | ||
|||+---------+||         |     | ||
||+-----------+|         |     | ||
|+-------------+---------+-----+-+|
+---------------------------------+
mile
źródło
Jeśli w moim języku nie ma zagnieżdżonych tablic, czy mogę zignorować definicję typu danych?
ThreeFx
1
@ThreeFx Możesz również wziąć dane wejściowe jako ciąg reprezentujący zagnieżdżoną tablicę
mile
To jest NAPRAWDĘ nieefektywne (w Haskell). Musiałbym parsować liczby ręcznie i tak dalej. W takim przypadku zdefiniowanie i użycie typu danych byłoby krótsze.
ThreeFx,
@TrzyreeFx Lub możesz uzupełnić tablicę wartościami wartownika, np. -1Ponieważ ograniczyłem również liczby całkowite, aby nie były ujemne. Następnie musiałbym wyczyścić dane wyjściowe dla tych niepoprawnych wartości.
mile
1
@MitchSchwartz Pewnie, weź dane wejściowe w zagnieżdżonej krotce lub innym formacie rodzimym dla twojego języka. Twoje wyniki są w porządku, dopóki pozostajesz spójny. Liczby całkowite można narysować u góry, pośrodku lub u dołu, a pola można u góry, pośrodku, u dołu lub rozciągnąć, aby wypełnić ich przestrzeń, tak jak w twoim przykładzie.
mile

Odpowiedzi:

4

Dyalog APL , 56 bajtów

Dzięki ngn za pomoc w usuwaniu około jednej trzeciej bajtów.

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

TryAPL

Zdefiniuj funkcję , a następnie uruchom każdy przypadek testowy i porównaj z wbudowanym ]Displaynarzędziem.
[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]]

Wyjaśnienie

Ogólnie rzecz biorąc, jest to anonimowa funkcja {...}na szczycie załącznika . Ta ostatnia dodaje tylko kolejny poziom zagnieżdżania, zachęcając pierwszą do dodania zewnętrznej ramki.

Funkcja anonimowa z białą spacją ( jest separatorem instrukcji):

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

Oto znowu, ale z oddzielnymi funkcjami narzędziowymi:

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

Teraz pozwól mi wyjaśnić każdą funkcję:

CloseBoxpobiera tabelę i zwraca tę samą tabelę, ale z pierwszą kolumną tabeli dołączoną po prawej stronie tabeli. Tak więc, biorąc pod uwagę tabelę 1 na 3 XYZ, ta funkcja zwraca tabelę 1 na 4 XYZXw następujący sposób:
 argument (lit. co jest po prawej)
, poprzedzony do
⊣/ lewej kolumny (lit. Zmniejszenie każdej z lewej strony rząd)

CreateVerticalbierze tabelę i zwraca ciąg znaków składający się ze znaków, które pasowałyby |s po bokach stołu, ale z dwoma +s poprzedzonymi, aby dopasować dwa rzędy -. Ostatecznie stół będzie cyklicznie obracany o jeden rząd, aby uzyskać pojedynczy +---...rząd powyżej i poniżej. Tak więc, biorąc pod uwagę dowolną tabelę z trzema  wierszami , funkcja ta zwraca ++|||następująco:
'++' , dwie plusy poprzedzone
'|' ⍴⍨ słupkiem przekształconym przez sumę
(wierszy) argumentu

AddHorizontalspobiera listę list, przekształca ją w tabelę, dodaje dwa wiersze -s na górze, dodaje odpowiadające znaki lewej krawędzi po lewej stronie, a następnie obraca jeden wiersz na dole, dzięki czemu tabela ma ramkę na górze , lewy i dolny. W następujący sposób:
1 ⊖ obróć jeden wiersz (górny wiersz przechodzi na dół)
CreateVertical , ciągu ++|||...poprzedzającego (jako kolumnę), aby
'-' ⍪⍣2 dodać minus dwa razy na początku
 argumentu przekształconego z listy list do tabeli

{Funkcja anonimowa }: jeśli argument jest prostą (nie zagnieżdżoną) listą, przekształć go w tablicę znaków (w ten sposób, biorąc pod uwagę listę 3-elementową 1 2 3, funkcja zwraca wizualnie identyczną tabelę 1 na 5 znaków 1 2 3). Jeśli argument nie jest prostą listą, upewnij się, że elementy są prostymi tablicami znaków; wyrównać je do równej wysokości; obramuj je u góry, u dołu i po lewej; połączyć je; i w końcu weź pierwszą kolumnę i dodaj ją po prawej stronie. W następujący sposób:
{ rozpocząć definicję funkcji anonimowej
  ⍵ ≡ ∊⍵:jeśli argument jest identyczna jak ta spłaszczona argumentu (czyli jest to prosta lista), a następnie:
    transponowania
    w układzie kolumnowym
    transpozycji
   ⍕ ⍵ stringified argumentu; else:
  CloseBox dodaj lewą kolumnę po prawej stronie
  ⊃ ,/ ujawniony (ponieważ zakrywa redukcja) łączone przekrojowego
  AddHorizontals¨ add -a na górze i na dole każdej
  ↓ ↑ ↓¨ wyściełanej do takiej samej wysokości * z
  ∇¨ ⍵  anonimowych funkcji stosuje się do każdej z argumentów
} końca definicji funkcji anonimowego
* Lit. ułóż każdą tabelę w listę list, połącz listy list (wypełnienie pustymi ciągami w celu wypełnienia krótkich wierszy) w tabelę, a następnie podziel tabelę na listę list

Adám
źródło
7

JavaScript (ES6), 223 203 bajtów

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 rozwiązania Ruby @ MitchSchwartz. Poprzednia wersja, która działała przez rekurencyjne owijanie tablic (i dlatego działała dla dowolnych treści, nie tylko liczb całkowitych):

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

Uwaga: Mimo że używam operatora rozkładania na mojej liście argumentów, aby uzyskać pożądane dane wyjściowe, podaj jeden parametr oryginalnej tablicy, a nie próbuj rozszerzyć tablicę; powoduje to zawijanie wyjścia w pożądane pudełko zewnętrzne. Niestety zewnętrzna skrzynka kosztuje mnie 18 bajtów, a rozdzielenie spacjami liczb całkowitych kosztuje mnie 8 bajtów, w przeciwnym razie dla 197 bajtów wystarczyłaby następująca wizualizacja:

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
źródło
Czy to obsługuje puste tablice? Otrzymuję błąd w Cannot read property 'map' of undefinedprzypadku pustych tablic, takich jak []. Bo [1,2,[]]ostatnia podtablica nie jest dla mnie wyświetlana.
mil
@miles Przepraszam, zapomniałem sprawdzić przypadki testowe, a teraz wszystkie działają. Nie określono danych wyjściowych dla, [1,2,[]]ponieważ przykłady pokazują tylko tablice zawierające liczby całkowite lub tablice, ale nie oba.
Neil
Świetny. Również nie wspominając o tym, że nie opisałem tego w testach, a problem będzie prostszy (ponieważ twój jest jak dotąd jedynym działającym wpisem), jeśli każda tablica jest jednorodna.
mil
3

Rubinowy, 104 bajty

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

Anonimowa funkcja oczekująca ciągu. Na przykład {{{{{4 3 2 1}}}}{{{3 2 1}}}{{2 1}}{1}}produkuje

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

Możesz użyć tego kodu do testowania:

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

Zaczyna się od środkowego rzędu i działa na zewnątrz. Po pierwsze, wystąpienia }{są zastępowane przez |. Następnie, podczas gdy nadal istnieją nawiasy klamrowe, wszystkie najbardziej wewnętrzne {...}ciągi są przekształcane w odpowiednie +-sekwencje, a znaki inne niż |{}w spacje. Na końcu stężenia pośrednie zamienia się w rury.

Mitch Schwartz
źródło
Skorzystałem z pewnych swobód z pozornie łagodnymi wymaganiami dotyczącymi formatowania danych wejściowych. W razie potrzeby kod można łatwo zmodyfikować, aby obsługiwał inny format wejściowy.
Mitch Schwartz,
Otrzymywanie źle przemyślanych komentarzy to jedna z największych radości z uczestnictwa w tej stronie.
Mitch Schwartz
3

Brainfuck, 423 bajty

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

Sformatowane z kilkoma komentarzami:

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

Wypróbuj online.

Oczekuje danych wejściowych sformatowanych jak (((((4 3 2 1))))(((3 2 1)))((2 1))(1))z końcowym znakiem nowej linii i generuje wynik formularza:

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

Podstawową ideą jest obliczenie, który znak ma zostać wydrukowany na podstawie głębokości zagnieżdżenia. Format wyjściowy jest taki, że indeks wiersza górnej ramki pola jest równy głębokości odpowiedniej tablicy, przy symetrii w środkowym rzędzie.

Taśma jest podzielona na 7-komórkowe węzły, przy czym każdy węzeł reprezentuje kolumnę na wyjściu.

Pierwsza pętla zużywa dane wejściowe i inicjuje węzły, śledząc głębokość i czy kolumna odpowiada nawiasowi (tj. Czy kolumna zawiera pionową ramkę), oraz zwijając występowanie )(pojedynczych węzłów.

Następna pętla generuje jeden wiersz na iterację. W obrębie tej pętli inna pętla przechodzi przez węzły i drukuje jeden znak na iterację; tutaj odbywa się większość pracy.

Podczas pętli inicjalizacji układ pamięci węzła na początku iteracji wynosi

x d 0 c 0 0 0

gdzie xjest flagą logiczną określającą, czy poprzedni znak był zamykającym nawiasiem, djest głębią (plus jeden) i cjest bieżącym znakiem.

Podczas pętli drukowania znaków układ pamięci węzła na początku iteracji wynosi

0 0 d1 d2 c p y

gdzie d1wskazuje głębokość w porównaniu ze wskaźnikiem wiersza dla górnej połowy; d2jest podobny do d1dolnej połowy; cjest znakiem wejściowym dla tej kolumny, jeżeli jest cyfrą lub spacją, w przeciwnym razie zero; pwskazuje fazę, tj. górną połowę, środkową lub dolną połowę; i yjest flagą, która rozprzestrzenia się od lewej do prawej, śledząc, czy dotarliśmy już do środkowego rzędu. Zauważ, że ponieważ ystaje się zero po przetworzeniu węzła, możemy użyć ykomórki poprzedniego węzła, aby uzyskać więcej przestrzeni roboczej.

Ta konfiguracja pozwala nam uniknąć jawnego obliczania maksymalnej głębokości podczas fazy inicjalizacji; yflaga jest back-propagowane zaktualizować pkomórki odpowiednio.

Po -1lewej stronie węzłów znajduje się komórka ułatwiająca nawigację, a po prawej stronie węzłów znajduje się komórka, która śledzi, czy wydrukowaliśmy jeszcze ostatni wiersz.

Mitch Schwartz
źródło
2

PHP + HTML, nie konkuruje ( 170 141 135 130 bajtów)

zapisano 29 bajtów zainspirowanych przez 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>";}

nie konkuruje, ponieważ nie ma wyjścia ascii i ponieważ pozwalam przeglądarce wykonać całą interesującą pracę

Tytus
źródło
1
Zamiast tego możesz tworzyć <b>tagi <div>i nie musisz określać koloru border. (Zapisywanie 9 bajtów)
SteeveDroz
Nie musisz w ogóle wstawiać <tag>, po prostu wyświetl wynik jako zwykły tekst, który pozwoli zaoszczędzić dużo bajtów (80 bajtów dla całego kodu po usunięciu HTML)
ClementNerma
@SteeveDroz Za pomocą <b>, mogę również usunąć white-spaceatrybut, oszczędzając kolejne 19 bajtów. świetny! I mogę wymienić paddingzmargin
Tytusa
2

JavaScript (ES6), 221

Funkcja nierekurencyjna zwracająca tablicę ciągów znaków (wciąż wykorzystująca wewnątrz podfunkcję rekurencyjną)

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

Działa to w 2 krokach.

Krok 1: rekurencyjnie zbuduj ciąg reprezentujący zagnieżdżoną tablicę wejściową. Przykład:

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

Oi Czaznacz otwieranie i zamykanie podtablicy. Proste tablice numeryczne są renderowane z elementami oddzielonymi spacją, natomiast jeśli elementy tablicy są podarunkami, są rozdzielane przecinkami. Ten ciąg śledzi wielopoziomowej struktury tablicy wejściowej, natomiast mogę środkowym rzędzie wyjście tylko wymianie OC,z |. Podczas rekurencyjnego budowania tego łańcucha temp, znajduję również maksymalny poziom głębokości i inicjalizuję tablicę pustych łańcuchów, które będą zawierać górną część wyniku.
Uwaga: pudełko zewnętrzne jest trudne, zagnieżdżam dane wejściowe w innej tablicy zewnętrznej, a następnie upuszczam pierwszy wiersz danych wyjściowych, który nie jest potrzebny

Krok 2: zeskanuj łańcuch tymczasowy i skompiluj dane wyjściowe

Teraz mam tablicę pustych ciągów, po jednym dla każdego poziomu. Skanuję łańcuch temp, śledząc bieżący poziom, który rośnie dla każdego Oi maleje dla każdego C. Wizualizuję to w ten sposób:

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

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

Plus plusy rosną i maleją zgodnie z bieżącym poziomem

Dla każdego znaku dodaję znak do każdego wiersza wyniku, przestrzegając następujących zasad:
- jeśli cyfra lub spacja, wstaw „-” na bieżącym poziomie i poniżej, umieść spację powyżej
- w przeciwnym razie umieść „+” na aktualny poziom, wpisz „-”, jeśli poniżej, i wpisz „|” jeśli powyżej

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

Podczas skanowania tymczasowego buduję również środkowy wiersz, zastępując OC,go|

Na końcu tego kroku mam górną połowę i środkowy rząd, muszę tylko odbić lustrzaną górę, aby uzyskać dolną połowę i gotowe

Kod mniej komentowany

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

)

Test

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
źródło
2

Rubinowy, 245 241 bajtów

Koszty ogólne potrzebne do zawinięcia wszystkiego w pudełka, a także wyrównania wszystkiego, są dość ciężkie ...

Generuje tablice ciągów, z jednym ciągiem na linię, zgodnie ze specyfikacją. Wyrównane do dołu zamiast wyrównanych do góry przypadków testowych, ponieważ pozwala zaoszczędzić 1 bajt.

Wypróbuj 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}
Wartość tuszu
źródło
@ Adám jest już naprawiony. Postaram się jak najlepiej zoptymalizować później ...
Wartość tuszu
Fajna, pierwsza odpowiedź z wyrównaniem do dołu. :-)
Adám
1

PHP, 404 bajtów

Wszystkie rozwiązania działają z maksymalną głębokością tablicy mniejszą niż 10. dla większych wartości głębokość musi być przechowywana w tablicy, a nie w ciągu.

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

Rozszerzony

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

za 425 bajtów możemy to zrobić za pomocą 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)));

Rozszerzony

$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 bajtów dla rozwiązania rekurencyjnego

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

Rozszerzony

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
źródło
1) $j!="]"?:$c--;-> $c-=$j=="]";(-2). 2) ($l=="]"?"":" ")-> " "[$l==$j](-5). Prawdopodobnie podobne podstawienia w drugiej pętli. 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=0nie jest potrzebny (-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) niepotrzebne białe znaki: foreach($e[0]as$f)(-1)
Tytus
9) niepotrzebne nawiasy w ($j==",")(-2). 10) if($r>"")$d.=+$c;-> $d.=$r>""?+$c:"";(-0)
Tytus
wersja rekurencyjna: 1) $d.=$l?$t;jest przestarzała (-10) 2) $s.=$l?"|":"";return$s;-> return$s."|"[$l];(-6). 3) przestarzałe nawiasy klamrowe {$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).
Tytus