Визуализируйте массив


26

Учитывая массив любой глубины, нарисуйте его содержимое с границами +-|вокруг каждого подмассива. Это символы ASCII для плюса, минуса и вертикальной трубы.

Например, если массив [1, 2, 3], рисовать

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

Для вложенного массива, такого как [[1, 2, 3], [4, 5], [6, 7, 8]], draw

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

Для рваного массива, например [[[1, 2, 3], [4, 5]], [6, 7, 8]], Draw

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

Обратите внимание, что после рисования остается больше места [6, 7, 8]. Вы можете нарисовать содержимое на верхней, центральной или самой нижней линии, но какой бы вы ни выбрали, вы должны оставаться последовательными.

Эта задача была вдохновлена коробка глагола <от J.

правила

  • Это поэтому выигрывает самый короткий код.
  • Встроенные функции, которые решают эту проблему, не допускаются.
  • Входной массив будет содержать только неотрицательные целочисленные значения или массивы. Каждый массив будет однородным, это означает, что его элементы будут либо только массивами, либо только целыми числами, но никогда не будут сочетать оба.
  • Каждый подмассив может быть вложен на любую глубину.
  • Вывод может быть либо в виде строки, либо в виде массива строк, где каждая строка является строкой вывода.

Тестовые случаи

[]
++
||
++

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

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

Если в моем языке нет вложенных массивов, могу ли я игнорировать определение типа данных?
ThreeFx

1
@ThreeFx Вы также можете принять входные данные в виде строки, представляющей вложенный массив
мили

Это действительно неэффективно (в Хаскеле). Я должен был бы разобрать числа вручную и так далее. В этом случае было бы короче определить и использовать тип данных.
ThreeFx

@ThreeFx Или вы можете заполнить массив значениями часового типа, так -1как я также ограничил целые числа неотрицательными. Тогда просто нужно очистить вывод для этих недопустимых значений.
миль

1
@MitchSchwartz Конечно, вводите данные в виде вложенного кортежа или любого другого формата, родного для вашего языка. Ваш вывод в порядке, пока вы остаетесь последовательным. Целые числа могут быть нарисованы сверху, в центре или снизу, а прямоугольники могут быть сверху, в центре, снизу или растянуты, чтобы заполнить их пространство, как в вашем примере.
миль

Ответы:


4

Дьялог АПЛ , 56 байт

Спасибо ngn за помощь в удалении около трети байтов.

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

TryAPL

Определите функцию , затем запустите каждый тестовый пример и сравните со встроенной ]Displayутилитой.
[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]]

объяснение

В целом, это анонимная функция {...}поверх приложения . Последний просто добавляет другой уровень вложенности, побуждая первый добавить внешний фрейм.

Анонимная функция с пробелами ( это разделитель операторов):

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

Здесь это снова, но с разделенными функциями полезности:

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

Теперь позвольте мне объяснить каждую функцию:

CloseBoxберет таблицу и возвращает ту же таблицу, но с первым столбцом таблицы, добавленным справа от таблицы. Таким образом, учитывая таблицу 1 на 3 XYZ, эта функция возвращает таблицу 1 на 4 XYZXследующим образом:
 аргумент (освещенный, который находится справа),
, добавленный к
⊣/ крайнему левому столбцу (освещенный уменьшением влево каждого ряд)

CreateVerticalберет таблицу и возвращает строку, состоящую из символов, которые бы подходили для |s по сторонам таблицы, но с двумя +s, добавленными перед двумя строками -. В конце концов таблица будет циклически вращаться на одну строку, чтобы получить одну +---...строку выше и ниже. Таким образом, для любой таблицы из трех строк эта функция возвращает ++|||следующее:
'++' , два плюса, добавленные к
'|' ⍴⍨ стилю, измененному в результате
 подсчета (строк) аргумента.

AddHorizontalsберет список списков, превращает его в таблицу, добавляет две строки -s сверху, добавляет соответствующие символы левого края слева, а затем поворачивает одну строку вниз, чтобы у таблицы была граница сверху слева и снизу. Как показано ниже:
1 ⊖ повернуть одну строку (верхняя строка переходит в нижнюю часть)
CreateVertical , строки с ++|||...добавленной (как столбец)
'-' ⍪⍣2 минус, дважды добавленной к вершине
 аргумента, преобразованного из списка списков в таблицу

{Анонимная функция }: если аргумент представляет собой простой (не вложенный) список, превратите его в таблицу символов (таким образом, учитывая список из 3 элементов 1 2 3, эта функция возвращает визуально идентичную таблицу символов размером 1 на 5 1 2 3). Если аргумент не является простым списком, убедитесь, что элементы - это простые таблицы символов; дополнить их до одинаковой высоты; рамка каждого сверху, снизу и слева; объединить их; и, наконец, возьмите самый первый столбец и добавьте его справа. Следующим образом:
{ начинайте определение анонимной функции,
  ⍵ ≡ ∊⍵:если аргумент идентичен сглаженному аргументу (т.  Е. Это простой список), затем:
    транспонируйте
   столбец
    транспонированного строкового
   ⍕ ⍵ аргумента; еще:
  CloseBox добавить крайний левый столбец справа от
  ⊃ ,/ раскрытое (потому что сокращение включает в себя) каскадное
  AddHorizontals¨ добавление -s сверху и снизу каждого из
  ↓ ↑ ↓¨ дополненных к равной высоте *
  ∇¨ ⍵  этой анонимной функции, примененной к каждому из аргументов,
} завершает определение анонимной функции
* Lit. сделать каждую таблицу списком списков, объединить списки списков (заполнение пустыми строками для заполнения коротких строк) в таблицу, а затем разбить таблицу на список списков списков


7

JavaScript (ES6), 223 203 байта

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

Порт решения @ MitchSchwartz для Ruby. Предыдущая версия, которая работала путем рекурсивного переноса массивов (и, следовательно, работала для произвольного содержимого, а не только целых чисел):

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

Примечание: хотя я использую оператор распространения в моем списке аргументов, чтобы получить желаемый результат, предоставьте один параметр исходного массива, а не пытайтесь расширять массив; это приводит к оборачиванию вывода в желаемую внешнюю коробку. К сожалению, внешний блок стоит мне 18 байтов, а разделение пробела целых чисел стоит мне 8 байтов, в противном случае для 197 байтов будет достаточно следующей альтернативной визуализации:

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]

Это обрабатывает пустые массивы? Я получаю сообщение об ошибке Cannot read property 'map' of undefinedдля пустых массивов, таких как []. Для [1,2,[]]последнего подмассива не отображается для меня.
миль

@miles Извините, я забыл проверить контрольные примеры, и теперь они все работают. Вы не указали выходные данные для, [1,2,[]]потому что в ваших примерах показаны только массивы, содержащие целые или массивы, но не оба.
Нил

Отлично. Также не берите в голову тот, который я не покрывал в тестовых примерах, и проблема будет более простой (так как ваша единственная рабочая запись до сих пор), если каждый массив является однородным.
миль

3

Рубин, 104 байта

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

Анонимная функция, которая ожидает строку. Например, {{{{{4 3 2 1}}}}{{{3 2 1}}}{{2 1}}{1}}производит

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

Вы можете использовать этот код для тестирования:

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

Это начинается со среднего ряда и работает наружу. Во-первых, случаи }{заменяются на |. Затем, пока еще есть фигурные скобки, все {...}самые внутренние строки преобразуются в соответствующие +-последовательности, а символы, отличные от |{}, превращаются в пробелы. В конце промежуточные скобы превращаются в трубы.


Я взял на себя смелость с явно снисходительными требованиями к форматированию ввода. Код может быть легко изменен для обработки другого формата ввода, если это необходимо.
Митч Шварц

Получение плохо продуманных комментариев - одна из самых больших радостей участия на этом сайте.
Митч Шварц

3

Brainfuck, 423 байта

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

Отформатировано с некоторыми комментариями:

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

Попробуйте онлайн.

Ожидает ввод, отформатированный как (((((4 3 2 1))))(((3 2 1)))((2 1))(1))завершающий символ новой строки, и производит вывод в виде:

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

Основная идея состоит в том, чтобы рассчитать, какой символ печатать на основе глубины вложения. Выходной формат таков, что индекс строки верхней границы блока равен глубине соответствующего массива с симметрией по средней строке.

Лента разделена на 7-элементные узлы, каждый из которых представляет столбец в выходных данных.

Первый цикл использует входные данные и инициализирует узлы, отслеживая глубину и соответствует ли столбец круглым скобкам (т. Е. Содержит ли столбец вертикальную границу), и объединяет вхождения )(в отдельные узлы.

Следующий цикл выводит по одной строке за итерацию. В этом цикле другой цикл пересекает узлы и печатает один символ за итерацию; именно здесь происходит большая часть работы.

Во время цикла инициализации макет памяти узла в начале итерации

x d 0 c 0 0 0

где x- логический флаг, определяющий, был ли предыдущий символ закрывающей скобкой, d- это глубина (плюс один) и cтекущий символ.

Во время цикла печати символов схема памяти узла в начале итерации

0 0 d1 d2 c p y

где d1указывает глубину по сравнению с индексом строки для верхней половины; d2похоже d1на нижнюю половину; cявляется символом ввода для этого столбца, если цифра или пробел, в противном случае ноль; pобозначает фазу, т.е. верхнюю половину, среднюю или нижнюю половину; и yэто флаг, который распространяется слева направо, отслеживая, достигли ли мы еще среднего ряда. Обратите внимание: поскольку yпосле обработки узла он становится равным нулю, мы можем использовать yячейку предыдущего узла, чтобы получить больше рабочего пространства.

Эта настройка позволяет нам избежать явного вычисления максимальной глубины на этапе инициализации; yфлаг обратно-размножают , чтобы обновить pклетки соответствующим образом .

Там есть -1клетка слева от узлов для облегчения навигации, и есть клетка справа от узлов, отслеживает ли мы напечатали последнюю строку еще.


2

PHP + HTML, не конкурирует ( 170 141 135 130 байт)

сохранено 29 байт, вдохновленных 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>";}

не конкурирует, потому что это не вывод ascii и потому что я позволю браузеру делать всю интересную работу


1
Вы можете сделать <b>теги вместо, <div>и вам не нужно указывать цвет border. (Экономия 9 байтов)
SteeveDroz

Вам вообще не нужно помещать тег <tag>, просто отображайте вывод в виде простого текста, который сэкономит много байтов (80 байтов для всего кода после удаления HTML)
ClementNerma

@SteeveDroz С помощью <b>я также могу удалить white-spaceатрибут, сохранив еще 19 байтов. отличный! И я могу заменить paddingнаmargin
Titus

2

JavaScript (ES6), 221

Нерекурсивная функция, возвращающая массив строк (все еще использующая рекурсивную подфункцию внутри)

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

Это работает в 2 этапа.

Шаг 1: рекурсивно построить строковое представление вложенного входного массива. Пример:

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

Oи Cотметьте открытие и закрытие подмассива. Простые числовые подмассивы отображаются с элементами, разделенными пробелом, а если элементы массива являются подмассивами, они разделяются запятыми. Эта строка отслеживает многоуровневую структуру входного массива, в то время как я могу получить среднюю строку вывода, просто заменив OC,на| . При рекурсивном построении этой временной строки я также нахожу максимальный уровень глубины и инициализирую массив пустых строк, который будет содержать половину верхней части выходных данных.
Примечание: внешний блок сложен, я вкладываю ввод в другой внешний массив, затем я отбрасываю первый ряд вывода, который не нужен

Шаг 2: отсканируйте временную строку и создайте вывод

Теперь у меня есть массив пустых строк, по одной для каждого уровня. Я сканирую временную строку, отслеживая текущий уровень, который увеличивается для каждого Oи уменьшается для каждого C. Я представляю это так:

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

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

Плюс вверх и вниз следуют за текущим уровнем

Для каждого символа я добавляю символ в каждую строку вывода, следуя правилам:
- если цифра или пробел, поставьте «-» на текущем уровне и ниже, поставьте пробел выше
- в противном случае поставьте «+» в текущий уровень, поставьте «-», если ниже, и «|» если выше

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

Во время сканирования темпа, я также построить средний ряд замену OC,с|

В конце этого шага у меня есть верхняя половина и средний ряд, мне нужно только отразить верхнюю часть, чтобы получить нижнюю половину, и я закончил

Меньше гольфа, прокомментированный код

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

)

Тест

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>


2

Рубин, 245 241 байт

Накладные расходы должны были обернуть все в коробки, а также выровнять все довольно тяжело ...

Выводит массивы строк, по одной строке на строку, согласно спецификации. Выровненный снизу вместо выровненных тестовых примеров, поскольку он сохраняет 1 байт.

Попробуйте онлайн!

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}

@ Adám это сейчас исправлено. Постараюсь сделать все возможное для дальнейшей оптимизации позже ...
Value Ink

Хороший. Первый ответ с выравниванием по дну. :-)
Адам

1

PHP, 404 байта

Все решения работают с максимальной глубиной массива, меньшей, чем 10. Для больших значений глубина должна храниться в массиве, а не в строке.

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

расширенный

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

для 425 байтов мы можем сделать это с помощью 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)));

расширенный

$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 байт для рекурсивного решения

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

расширенный

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

1) $j!="]"?:$c--;-> $c-=$j=="]";(-2). 2) ($l=="]"?"":" ")-> " "[$l==$j](-5). Скорее всего, аналогичные замены во втором цикле. 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=0не нужно (-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) ненужные пробелы: foreach($e[0]as$f)(-1)
Тит

9) ненужные скобки в ($j==",")(-2). 10) if($r>"")$d.=+$c;-> $d.=$r>""?+$c:"";(-0)
Тит

рекурсивная версия: 1) $d.=$l?$t;устарела (-10) 2)$s.=$l?"|":"";return$s; -> return$s."|"[$l];(-6). 3) устаревшие брекеты {$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).
Тит
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.