Примечание. Это №2 в серии задач по манипулированию массивами . Для предыдущего вызова нажмите здесь .
Разделение вложенных списков
Чтобы разделить значения во вложенном списке, выровняйте его, а затем оберните каждое значение так, чтобы оно было на той же глубине вложенности, что и раньше.
То есть этот список:
[1, [2, 3], [4, 4, [5, 2], 1]]
Станет:
[1, [2], [3], [4], [4], [[5]], [[2]], [1]]
Соревнование
Ваша задача - написать программу, которая берет любой вложенный список натуральных чисел (в пределах вашего языка) и выполняет эту операцию разделения.
Вы можете отправить функцию, которая принимает список в качестве аргумента, или полную программу, которая выполняет ввод / вывод.
Поскольку это код-гольф , выигрывает самое короткое представление (в байтах)! *
* Стандартные лазейки для гольфа запрещены. Вы знаете, что делать.
Тестовые случаи
Входные списки будут содержать только целые числа в стандартном целочисленном размере вашего языка. Чтобы избежать языковых ограничений, мешающих им конкурировать, значения не будут вкладываться на глубину более 10.
Вы можете предположить, что входные данные не будут иметь пустых подсписков: например, - [[5, []]]
не будет дано. Тем не менее, основной список может быть пустым.
[] -> []
[[1, 2]] -> [[1], [2]]
[3, [4, 5]] -> [3, [4], [5]]
[3, [3, [3]]] -> [3, [3], [[3]]]
[[6, [[7]]]] -> [[6], [[[7]]]]
[[5, 10], 11] -> [[5], [10], 11]
Не стесняйтесь оставлять комментарии, если я пропустил угловой случай.
пример
Я бросил вместе быстрый (ungolfed) Python решение 3 в качестве примера - вы можете проверить его на repl.it .
источник
Ответы:
Брахилог , 16 байт
Попробуйте онлайн!
объяснение
источник
Z
аргумент делает на TIO? Без этого это, кажется, выводит с истиной / ложью, что заставляет это казатьсяZ
необходимым в подсчете байтов.Z
сообщает Brachylog, что выходной аргумент является переменной. Эта переменная объединяется с полученным результатом. Когда вы удаляете его, он сообщает Brachylog, что вывод является анонимной переменной, и вместо этого выводит, будет ли основной предикат успешным или нет. Это то же самое, что и в Прологе, где результат «помещается» в переменную.Mathematica,
2421 байтили один из них:
объяснение
Причина, по которой это так коротко, состоит в том, что это в основном рекурсия, которая не требует явного базового случая.
Здесь много синтаксического сахара, поэтому давайте начнем с того, что раскусим это.
&
обозначает безымянную функцию слева от нее, аргумент которой записывается как#
. Внутри эта функция#0
относится к самой функции, которая позволяет писать безымянные рекурсивные функции. Но давайте начнем с присвоения внутренней функции имени и извлечения его:Другим важным синтаксическим сахаром является то,
f/@x
что является сокращением,Map[f, x]
т. Е. Он вызываетf
каждый элементx
. Причинаf[x_] := ... f /@ x
не приводит к бесконечной рекурсии в том, что отображение чего-либо на атоме оставляет атом неизменным без фактического вызова функции. Следовательно, нам не нужно явно проверять базовый случай (текущий элемент - целое число).Таким образом, функция
f
сначала возвращается к самому глубокому списку внутриx
, после чегоf/@
становится недоступной . Тогда мы называем использование##& @@ List /@
на этом. ОтображениеList
по списку просто оборачивает каждый элемент в отдельный список, поэтому{1, 2, 3}
становится{{1}, {2}, {3}}
. Затем мы применяем##&
к нему, что означает, что заголовок (то есть внешний список) заменяется на##&
, так что это превращается в##&[{1}, {2}, {3}]
. Но##&
просто возвращает свои аргументы какSequence
(который вы можете рассматривать как развернутый список или своего рода оператор «splat» в других языках).Таким образом,
##& @@ List /@
превращает список{1, 2, 3}
в{1}, {2}, {3}
(вид, что последняя вещь на самом деле завернута в головуSequence
, но она исчезает, как только мы используем значение где-либо).Это оставляет вопрос, почему
f
само по себе не является решением проблемы. Проблема в том, что внешний список должен обрабатываться по-разному. Если у нас есть вклад,{{1, 2}, {3, 4}}
мы хотим,{{1}, {2}, {3}, {4}}
а нет{{1}}, {{2}}, {{3}}, {{4}}
. Мое оригинальное решение исправило это, передав окончательный результат в виде списка аргументов,Join
который восстановил бы внешний уровень списков, но этот просто пропускает внешний уровень, используяf
себя в карте на выходе. Следовательно,f
применяется только к отдельным элементам внешнего списка и никогда не касается этого списка.Что касается других трех решений, то первое просто применяет рекурсию, за пределами
f
которой работает так же хорошо. Два других решения избегают повторнойMap
операции, сначала объединяя две функции, а затем отображая результат только один раз.источник
J ,
1918 байтЭто анонимный глагол, который принимает и возвращает коробочные массивы, которые являются J (довольно громоздкой) версией вложенных массивов. Посмотрите, как пройти все тестовые случаи.
объяснение
При этом используются несколько экзотические операции
{::
( map ) иS:
( spread ), которые работают с массивами в штучной упаковке.{::
заменяет каждый лист в штучной упаковке путь к этому листу.S:
применяет данный глагол к заданной глубине вложения, а затем разбивает результаты в массив.источник
R, 199 байт
Этот вопрос был трудным. Списки R немного странные, и абсолютно не просто зациклить все элементы подсписков. Также непросто определить глубину этого списка. Затем возникает задача воссоздать список со всеми разделенными элементами, поэтому нам также необходим способ адаптивного создания списка определенной глубины.
Решение состоит из двух больших частей. Рекурсивная функция, которая перебирает все списки и записывает глубину:
Когда мы
unlist(l)
сохраняем глубину каждой записи вектора ,d
мы неявно создаем списокlapply
и заполняем его следующей функцией:В этом вызове apply мы создаем объект
q
со значением записи в списке, проверяем его глубину и проверяем, не равен ли он нулю. Если он равен нулю, мы можем просто оставить его как числовое значение. Если он ненулевой, нам нужно вложить его в такое количество списков. Таким образом, мы вызываем цикл ford
и повторяем вызовq=list(q)
.lapply
затем помещает все эти значенияq
в список, создавая желаемый результат.Полная программа с правильным интервалом и такими:
источник
is.list(y)
вместоclass(y)=='list'
? не могу убедиться, что это на самом деле будет работать.Сетчатка , 34 байта
Попробуйте онлайн!
источник
(?<-2>)
работает?C (gcc), 147 байтов
Пример ввода:
Пример вывода:
источник
сложенный , неконкурентный, 25 байтов
Это функция, которая изменяет верхний элемент стека. Если вы хотите истинную функцию, просто добавьте
[
и]
в начало и в конец. Попробуй это здесь!Вот читаемая версия:
Прецедент:
Вывод без перевода строки:
источник
*
как аргумент для блока кода?d-1
.$func
это функция, которой можно манипулировать.PHP,
10194 байтаспас 1 байт благодаря @Christoph, сохранил еще 6 вдохновленных этим.
рекурсивная функция, довольно прямолинейная
сломать
источник
$r
получает элементы в цикле, либо функция возвращает пустой массив. Это может привести к уведомлениям, но они не распечатываются с конфигурацией по умолчанию.!cos()
.cos()
возвращаетnull
для каждого массива и float! = 0 для каждого положительного целого числа. Я имею в виду ... кого волнуют предупреждения?is_int
: изменение состояния ничего не сохраняет; Мне нужно пространство междуelse
иforeach
. НО:$b[0]
целое число естьNULL
.Python 2,
122106 байтДовольно ужасная оценка, просто прямая реализация.
Спасибо @Zachary T за помощь в сохранении 16 байтов!
Вызов
x
с одним аргументом для запуска. По какой-то причине он может быть запущен только один раз.источник
a+=[n(l,d)]
наa+=n(l,d),
(обратите внимание на запятую)t
?n
к функции и удалить первый аргумент, так как он всегда будетl
.JavaScript (Firefox 30-57), 53 байта
Лучший ответ ES6, который у меня есть, составляет 76 байт:
источник
f=
.Pyth - 29 байт
Тестовый пакет .
источник
Perl 6 ,
6047 байт( Попробуйте онлайн. )
Объяснение:
[... for |$^a]
: Переберите входной массив и создайте из него новый массив.$_ ~~ List ?? ... !! ...
: Для каждого элемента проверьте, является ли он самим массивом.|([$_] for .&f)
Если элемент является массивом, рекурсивно примените к нему функцию, переберите элементы нового массива, возвращенного этим рекурсивным вызовом, оберните каждый элемент в свой собственный массив и вставьте их во внешний список.$_
: Если элемент не является массивом, передайте его как есть.источник
Haskell, 71 байт
Опять же, я должен определить свой собственный тип списка, потому что списки natives в Haskell не могут быть произвольно вложенными. Этот новый тип
L
может быть возвращен из функции, но не может быть напечатан по умолчанию, поэтому, чтобы увидеть результат, я определяюshow
экземпляр дляL
:Теперь мы можем сделать тест в REPL:
Как это работает: простая рекурсия, которая проходит уровень вложенности как функция
C
конструкторов. Мы начинаем с функции идентификацииid
и всякий раз, когда есть список (-> сопоставление с образцомd#C l=
), мы добавляем дополнительный слойC
(->C .pure.d
) к рекурсивному вызову#
всех элементов списка. Если мы встречаем число, мы просто применяем функцию nesting-leveld
к числу.источник
APL (Dyalog) , 44 байта *
Функция анонимного молчаливого префикса. Принимает вложенный список APL в качестве аргумента и возвращает вложенный массив APL.
Попробуйте онлайн!
{
…}
Применить следующую явную функцию, где аргумент представлен⍵
:⎕JSON⍵
преобразовать аргумент в JSONj←
хранить вj
'[]'∘.=
таблица, в которойj
равны открытые (верхний ряд) и закрытые (нижний ряд) скобки-⌿
верхний ряд минус нижний ряд (уменьшение вертикальной разности)+\
накопленная сумма (это дает уровень вложенности для каждого символа)(
…)⊆
Раздел, начинающий новый раздел, если 1 не предшествует 1 в…j∊⎕D
где каждый символj
является членом множества D igits⊃¨
выберите первый из каждого (это дает уровень вложенности для каждого многозначного числа)∊{
…}¨
Применить следующую функцию к каждому уровню вложения (⍵
), используя соответствующий элемент из аргумента ϵ nlisted (плоский) в качестве левого аргумента (⍺
):,⍺
ravel (listify) число (потому что скаляры не могут быть вложены)⊂⍣⍵
приложить⍵
раз⊃
раскрыть (потому что самый внутренний список сам по себе является приложением)* Использование Dyalog Classic , с
⎕ML←3
( по умолчанию на многих системах), подставляя⊂
для⊆
и↑
для⊃
. Тио!источник