Учитывая массив любой глубины, нарисуйте его содержимое с границами +-|
вокруг каждого подмассива. Это символы 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|||||+-----+|| | ||
||||+-------+|||+-------+| | ||
|||+---------+|| | | ||
||+-----------+| | | ||
|+-------------+---------+-----+-+|
+---------------------------------+
-1
как я также ограничил целые числа неотрицательными. Тогда просто нужно очистить вывод для этих недопустимых значений.Ответы:
Дьялог АПЛ , 56 байт
Спасибо ngn за помощь в удалении около трети байтов.
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]]
объяснение
В целом, это анонимная функция
{...}
поверх приложения⊂
. Последний просто добавляет другой уровень вложенности, побуждая первый добавить внешний фрейм.Анонимная функция с пробелами (
⋄
это разделитель операторов):Здесь это снова, но с разделенными функциями полезности:
Теперь позвольте мне объяснить каждую функцию:
CloseBox
берет таблицу и возвращает ту же таблицу, но с первым столбцом таблицы, добавленным справа от таблицы. Таким образом, учитывая таблицу 1 на 3XYZ
, эта функция возвращает таблицу 1 на 4XYZX
следующим образом:⊢
аргумент (освещенный, который находится справа),,
добавленный к⊣/
крайнему левому столбцу (освещенный уменьшением влево каждого ряд)CreateVertical
берет таблицу и возвращает строку, состоящую из символов, которые бы подходили для|
s по сторонам таблицы, но с двумя+
s, добавленными перед двумя строками-
. В конце концов таблица будет циклически вращаться на одну строку, чтобы получить одну+---...
строку выше и ниже. Таким образом, для любой таблицы из трех строк эта функция возвращает++|||
следующее:'++' ,
два плюса, добавленные к'|' ⍴⍨
стилю, измененному в результате≢
подсчета (строк) аргумента.AddHorizontals
берет список списков, превращает его в таблицу, добавляет две строки-
s сверху, добавляет соответствующие символы левого края слева, а затем поворачивает одну строку вниз, чтобы у таблицы была граница сверху слева и снизу. Как показано ниже:1 ⊖
повернуть одну строку (верхняя строка переходит в нижнюю часть)CreateVertical ,
строки с++|||...
добавленной (как столбец)'-' ⍪⍣2
минус, дважды добавленной к вершине↑
аргумента, преобразованного из списка списков в таблицу{
Анонимная функция}
: если аргумент представляет собой простой (не вложенный) список, превратите его в таблицу символов (таким образом, учитывая список из 3 элементов1 2 3
, эта функция возвращает визуально идентичную таблицу символов размером 1 на 51 2 3
). Если аргумент не является простым списком, убедитесь, что элементы - это простые таблицы символов; дополнить их до одинаковой высоты; рамка каждого сверху, снизу и слева; объединить их; и, наконец, возьмите самый первый столбец и добавьте его справа. Следующим образом:{
начинайте определение анонимной функции,⍵ ≡ ∊⍵:
если аргумент идентичен сглаженному аргументу (т. Е. Это простой список), затем:⍉
транспонируйте⍪
столбец⍉
транспонированного строкового⍕ ⍵
аргумента; еще:CloseBox
добавить крайний левый столбец справа от⊃ ,/
раскрытое (потому что сокращение включает в себя) каскадноеAddHorizontals¨
добавление-
s сверху и снизу каждого из↓ ↑ ↓¨
дополненных к равной высоте *∇¨ ⍵
этой анонимной функции, примененной к каждому из аргументов,}
завершает определение анонимной функции* Lit. сделать каждую таблицу списком списков, объединить списки списков (заполнение пустыми строками для заполнения коротких строк) в таблицу, а затем разбить таблицу на список списков списков
источник
JavaScript (ES6),
223203 байтаПорт решения @ MitchSchwartz для Ruby. Предыдущая версия, которая работала путем рекурсивного переноса массивов (и, следовательно, работала для произвольного содержимого, а не только целых чисел):
Примечание: хотя я использую оператор распространения в моем списке аргументов, чтобы получить желаемый результат, предоставьте один параметр исходного массива, а не пытайтесь расширять массив; это приводит к оборачиванию вывода в желаемую внешнюю коробку. К сожалению, внешний блок стоит мне 18 байтов, а разделение пробела целых чисел стоит мне 8 байтов, в противном случае для 197 байтов будет достаточно следующей альтернативной визуализации:
источник
Cannot read property 'map' of undefined
для пустых массивов, таких как[]
. Для[1,2,[]]
последнего подмассива не отображается для меня.[1,2,[]]
потому что в ваших примерах показаны только массивы, содержащие целые или массивы, но не оба.Рубин, 104 байта
Анонимная функция, которая ожидает строку. Например,
{{{{{4 3 2 1}}}}{{{3 2 1}}}{{2 1}}{1}}
производитВы можете использовать этот код для тестирования:
Это начинается со среднего ряда и работает наружу. Во-первых, случаи
}{
заменяются на|
. Затем, пока еще есть фигурные скобки, все{...}
самые внутренние строки преобразуются в соответствующие+-
последовательности, а символы, отличные от|{}
, превращаются в пробелы. В конце промежуточные скобы превращаются в трубы.источник
Brainfuck, 423 байта
Отформатировано с некоторыми комментариями:
Попробуйте онлайн.
Ожидает ввод, отформатированный как
(((((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
клетка слева от узлов для облегчения навигации, и есть клетка справа от узлов, отслеживает ли мы напечатали последнюю строку еще.источник
PHP + HTML, не конкурирует (
170141135130 байт)сохранено 29 байт, вдохновленных SteeveDroz
не конкурирует, потому что это не вывод ascii и потому что я позволю браузеру делать всю интересную работу
источник
<b>
теги вместо,<div>
и вам не нужно указывать цветborder
. (Экономия 9 байтов)<b>
я также могу удалитьwhite-space
атрибут, сохранив еще 19 байтов. отличный! И я могу заменитьpadding
наmargin
JavaScript (ES6), 221
Нерекурсивная функция, возвращающая массив строк (все еще использующая рекурсивную подфункцию внутри)
Это работает в 2 этапа.
Шаг 1: рекурсивно построить строковое представление вложенного входного массива. Пример:
[[[1, 2, 3], [],[4, 5]], [6, 7, 8]]
->"OOO1 2 3,,4 5C,6 7 8CC"
O
иC
отметьте открытие и закрытие подмассива. Простые числовые подмассивы отображаются с элементами, разделенными пробелом, а если элементы массива являются подмассивами, они разделяются запятыми. Эта строка отслеживает многоуровневую структуру входного массива, в то время как я могу получить среднюю строку вывода, просто заменивOC,
на|
. При рекурсивном построении этой временной строки я также нахожу максимальный уровень глубины и инициализирую массив пустых строк, который будет содержать половину верхней части выходных данных.Примечание: внешний блок сложен, я вкладываю ввод в другой внешний массив, затем я отбрасываю первый ряд вывода, который не нужен
Шаг 2: отсканируйте временную строку и создайте вывод
Теперь у меня есть массив пустых строк, по одной для каждого уровня. Я сканирую временную строку, отслеживая текущий уровень, который увеличивается для каждого
O
и уменьшается для каждогоC
. Я представляю это так:Плюс вверх и вниз следуют за текущим уровнем
Для каждого символа я добавляю символ в каждую строку вывода, следуя правилам:
- если цифра или пробел, поставьте «-» на текущем уровне и ниже, поставьте пробел выше
- в противном случае поставьте «+» в текущий уровень, поставьте «-», если ниже, и «|» если выше
Во время сканирования темпа, я также построить средний ряд замену
OC,
с|
В конце этого шага у меня есть верхняя половина и средний ряд, мне нужно только отразить верхнюю часть, чтобы получить нижнюю половину, и я закончил
Меньше гольфа, прокомментированный код
)
Тест
источник
Рубин,
245241 байтНакладные расходы должны были обернуть все в коробки, а также выровнять все довольно тяжело ...
Выводит массивы строк, по одной строке на строку, согласно спецификации. Выровненный снизу вместо выровненных тестовых примеров, поскольку он сохраняет 1 байт.
Попробуйте онлайн!
источник
PHP, 404 байта
Все решения работают с максимальной глубиной массива, меньшей, чем 10. Для больших значений глубина должна храниться в массиве, а не в строке.
расширенный
для 425 байтов мы можем сделать это с помощью REGEX
расширенный
455 байт для рекурсивного решения
расширенный
источник
$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)($j==",")
(-2). 10)if($r>"")$d.=+$c;
->$d.=$r>""?+$c:"";
(-0)$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).