В этой задаче ваша задача состоит в том, чтобы создать программу, которая принимает вложенный массив и возвращает одномерный плоский массив. Например [10,20,[30,[40]],50]
должен выводить [10,20,30,40,50]
.
вход
Входными данными будет вложенный массив (например, [10,20,[[[10]]]]
). Он будет содержать только целые числа (как отрицательные, так и положительные), строки и массивы. Вы можете принять входные данные как аргумент функции, STDIN или любой другой, который подходит вашему языку. Вы можете предположить, что входной массив не будет иметь пустой массив.
Выход
Выходными данными будет плоский одномерный массив с теми же элементами того же типа, что и во вложенном массиве и в том же порядке.
Тестовые случаи
[10,20,30] -> [10,20,30]
[[10]] -> [10]
[["Hi"],[[10]]] -> ["Hi",10]
[[[20],["Hi"],"Hi",20]] -> [20,"Hi","Hi",20]
[[["[]"],"[]"]] -> ["[]","[]"]
Не стесняйтесь просить любые разъяснения, используя комментарии. Это код-гольф , поэтому выигрывает самый короткий код в байтах!
Примечание: если ваш язык содержит встроенный для этого, вы не должны его использовать.
редактировать
Пожалуйста, включите ссылку на сайт, где ваш код может быть выполнен.
источник
unflatten
вопрос, но нетflatten
вопроса о PPCG.["[",[["[",],'[',"['['"]]
в качестве контрольного примера.'
и в"
качестве разделителей. (Но я согласен , что тест с участием[
,]
,"
и\
внутри строки , было бы полезно.)Ответы:
К, 3 байта
Это довольно распространенная идиома. «Присоединяйся, сходись».
попробуйте здесь с ОК .
Как это работает:
Join (
,
) объединяет атомы или списки для создания списка. Over (/
) принимает глагол (в данном случае соединение) и применяет его между каждым элементом списка слева направо. Таким образом, соединение,/
сгладит все элементы верхнего уровня списка. Символ на/
самом деле имеет разные значения в зависимости от валентности (числа аргументов) глагола, с которым он составлен. Когда мы предоставляем,/
глагол, финал/
действует как «сходящийся» - он многократно применяется,/
к вводу, пока не прекратит изменяться. Некоторые другие языки называют такую функцию «комбинатором с фиксированной точкой». Повторяя слияние списков нижнего уровня, вы в конечном итоге получите единый плоский список, и ни одна из операций не изменит порядок элементов. Кажется, это решает проблему.источник
JavaScript (ES6), 35 байт
Вдохновленный ответом @ user81655 :
источник
Mathematica,
1614 байтовБезымянная функция, которая принимает и возвращает список, например:
объяснение
Синтаксическая сахарная вечеринка!
Чтобы понять , как это работает, обратите внимание , что каждое выражение в Mathematica является либо атом (например , числа, строки, символы) или соединение выражение вида
f[a, b, c, ...]
, гдеf
,a
,b
,c
сами являются произвольными выражениями. Здесьf
называется глава выражения. Все остальное помимо этого - просто синтаксический сахар. Например,{a, b, c}
это простоList[a, b, c]
.Мы начнем с того,
//@
что отображает функции на всех уровнях списка. Например:Обратите внимание, что это сопоставляет
f
атомы, а также составные выражения. Сейчас мы ищем способ избавиться от заголовков списка и сохранить все остальное.Apply
Функция обычно используется для подачи элементов списка в виде отдельных аргументов функции, но его фактическое определение является более общим и просто заменяет главу выражения. НапримерApply[g, f[a, b]]
даетg[a, b]
.Теперь есть специальная «голова» под названием,
Sequence
которая просто исчезает. Например,{a, Sequence[b, c], d}
просто оценивает{a, b, c, d}
. Идея выравнивания списка состоит в том, чтобы заменить заголовки всех внутренних списковSequence
так, чтобы они попали в окружающий их список. Так что мы хотим, чтобыApply
головаSequence
к спискам. Удобно, если мыApply
что- то добавляем к атому, он просто оставляет атом неизменным, поэтому нам вообще не нужно различать типы выражений.Наконец, есть одна маленькая проблема:
f
также применяется к внешнему уровню, так что он также удаляет самый внешнийList
, что нам не нужно. Самый короткий способ противостоять этому - просто снова обернуть результат в список, чтобы окружениеSequence
могло безопасно исчезнуть.Обратите внимание, что нет
Apply
ниSequence
в коде.@@
является операторской формойApply
и##&
является стандартной игрой в гольф для сокращения длинного встроенного имениSequence
. Так что немного раскусывая, мы получаем что-то вроде:Для получения более подробной информации о том, как и почему
##&
работает, см. Раздел «Последовательности аргументов» в моем ответе на советы Mathematica .источник
//@
. Очень полезно знать о!//@
захватывает аккуратный образец. Напоминает мне некоторые из рекурсивных комбинаторов в Joy. У вас есть ссылка на хорошую ссылку на какие-либо связанные функции в Mathematica? Я очень заинтересован в способах факторизации явной рекурсии вне программ.Map
,MapAt
,Apply
, а такжеReplace
и связанные с ними функции. В общем, хотя есть много функций, которые принимают необязательный параметр levelpec (см. Мое оригинальное 16-байтовое решение), который позволяет применять функцию на нескольких / всех уровнях одновременно.Python 2, 43 байта
В списке рекурсивно обращается к элементам и объединяет результаты. На строке или числе, в единственном списке.
К сожалению, Python 2 упорядочивает типы
int < list < string
сэндвичейlist
между остальными, что требует проверки двух неравенств. Таким образом, вместо этогоl*0
проверяется пустой список[]
, в противном случае дает0
или""
.источник
Рубин,
434234 байтаРекурсивное решение. Теперь с обработкой исключений! (можно также отдать должное @akostadinov за поддержку изменений)
IDEOne ссылка
источник
rescue
подобноеtry
блока, поэтомуbegin
вместо этого вы используете для разграничения те части, которые вы хотите поймать, и части, которые у вас нет. Так что, так как вы ловите весь остальной блок перед этим, вам это технически не нужно? Остальное - это просто обрезанный пробел, так как Ruby интерпретирует строку как...inject(:+) rescue [a]
a = raise("haha") rescue 1
, назначил1
быa
. Этоrescue
, как есть инлайнif
иwhile
.JavaScript (ES6), 41 байт
источник
Perl 6 , 24 байта
Объяснение:
Тест:
источник
Haskell, 43 байта
У Haskell нет ни вложенных списков с различной глубиной подсписков, ни смешанных типов для элементов списка. Для вложения я определяю пользовательский тип данных,
D
который является либо листом,L
который содержит некоторый элемент, либо узлом,N
который является спискомD
s. Для смешанных элементов здесь используется предопределенный тип данных,Either
который объединяет два типа в одинEither String Integer
. Новый типD
и функция flattenf
полностью полиморфны в типе листовых элементов, поэтому мне не нужно особо заботиться о чем-либоEither
.Пример использования:
f (N[N[L(Right 20)], N[L(Left "Hi")], L(Left "Hi") , L(Right 20)])
->[Right 20,Left "Hi",Left "Hi",Right 20]
.источник
Pyth,
765 байтПопробуйте онлайн: демонстрация или тестовый набор
Но, конечно же, есть встроенная функция, которая обрабатывает задачу всего за 2 байта:
.n
( Test Suite )источник
G
неявно добавляет последний символ , если я его не напишу.JavaScript (Firefox 30-57), 43 байта
Просто потому, что я мог даже избежать использования
concat
.источник
[for(of)]
доступно только в Firefox 30+. Это было предложено для ES7, но позже уронили.for(__ in __)
Perl,
3429 байтФункции.
Если нужно сгладить список вроде
my @a = f(@a)
, 29 байт:Проверьте это на Ideone
Если необходимо сгладить массив как ref
my $a = f($a)
, 34 байта:Проверьте это на Ideone .
Perl 5.22.0+, 27 байт
Благодаря Хоббс .
Если нужно сгладить список вроде
my @a = f(@a)
27 байтов:Проверьте это на JDoodle
Если необходимо сгладить массив как ref
my $a = f($a)
, 32 байта:Проверьте это на JDoodle .
источник
?@{f@$_}:
должно работать вместо?@{f(@$_)}:
сохранения двух байтов.f
это функция, потому чтоf
еще не объявлена.sub f{}sub f{... f@$_ ...}
за работой.ref
Паренсу не нужно работать, экономя 2 байта. 2. Насколько я вижу,sub f{map{ref?f(@$_):$_}@_}
находится в правилах и сохраняет еще 5.f
принимает массив (nonref) в качестве списка, чтобы он мог вернуть то же самое.ref
то компилятор предполагает , что?
начинает?PATTERN?
работу , какref(?PATTERN?)
. Поэтому компилятор ищет вторую?
и выдает ошибку.?PATTERN?
был удален в 5.22.0 (m?PATTERN?
все еще работает), и я тестирую последнюю версию. Таким образом, вы можете получить эти два байта, указав 5.22+.Юлия, 29 байт
Это рекурсивное разделение на конкатенационные функции до достижения фиксированной точки. пример
источник
Сетчатка , 30 байт
Попробуйте онлайн! (Первая строка используется только для запуска нескольких тестовых случаев одновременно.)
Retina не имеет понятия массивов, строковых литералов или чисел, поэтому я решил использовать «общий» формат ввода
[...,...]
массивов стилей и"
строк -delimited, где\
можно использовать внутри строк для экранирования любого символа (в частности"
и\
самого себя).Сама программа просто сопоставляет либо полную строку, либо квадратные скобки, и заменяет их тем,
$1
что сохраняет строки и удаляет квадратные скобки. Предел1>
пропускает первый матч, чтобы мы не удаляли ведущие[
. Тем не менее, это удаляет трейлинг]
, поэтому мы добавляем его обратно на отдельном этапе.источник
Пайк, 11 байт
Попробуй это здесь!
Объяснение:
Или 7 байт после исправления
Попробуй это здесь!
Объяснение:
Или даже 2 байта, если печать на стандартный вывод разрешена (это может быть встроено)
Попробуй это здесь!
Это глубоко применяет
print_newline
функцию к каждому непоследовательному элементу на входе и рекурсивным элементам последовательности.источник
Java (v8)
390276 байтПросто для полноты и все такое. :) Не могу сказать, что Java-код эффективен.
источник
oaf
наo
и изменитьflatten
наf
.final
s, все это может быть лямбда, вам не нужноpublic static
...false
с1>2
, а также дополнительные 2 байта вы могли бы получить , если вы объявите п , но не определяет (компилятор автоматически определить его как 0)Python, 57 байт
Попробуйте онлайн: Python 2 , Python 3
Спасибо Кевину Лау за
list==type(x)
трюк.источник
type(x)==list
короче чемisinstance(x,list)
.[`x`>'['and...
? (Это работает только в Python 2.)Рубин
есть встроенный
flatten
метод.Вы можете запустить здесь: http://www.tutorialspoint.com/execute_ruby_online.php
Один 43 байта, но думал поделиться:
Один 45 байт, который более эффективен, чем предыдущий, а другой ответ ruby:
вот эталон:
результат:
источник
Note: If your language contains a built-in for this, then you must NOT use it
.rescue
rescue
выглядит довольно медленно, кстати, какtry/catch
в javaPerl,
3934 + 1 (-p
флаг) 35 байтОдин лайнер. Вдохновленный Мартином Бюттнером .
Проверьте это на Ideone .
источник
Clojure, 68 байт
mapcat
сначала применяет функцию к каждому элементу, а затем объединяет результаты. Таким образом, каждый раз, когда он совпадает, один «уровень вложенности» теряется. Concat не работает с не последовательностями, поэтому элементы должны быть обернуты в вектор, если они не являются векторными.Вы можете попробовать это здесь: http://www.tryclj.com
источник
ANSI C, 193 байта
:-/, какие-либо предложения? Кстати, я попытался найти сетевой источник для компиляции, но WL строго для этого кода для компиляции. В противном случае он будет работать для VS и GCC.
источник
JavaScript 20 байт
Массив + массив равен array.toString
источник
a
является аргументом функции. Я постараюсь отредактировать функцию сейчас.a=>
ее в начало кода.C #, 48 байтов
Думал, что я также опубликую это, так как никто еще не дал решения C #. Предложения приветствуются!
источник
i
инициализируется? и вы уверены, что это работает на[["[]"],"[]"]
примере?i=>$"{i.Replace("[","").Replace("]","")}"
?Ракетка, 63 байта
источник
Java 8 165 символов
Развёрнутый в классе:
Этот ответ основан на подходе Джереми Хартона . Я использовал его, изменил его в некоторых местах и создал более похожую на гольф версию.
источник
JavaScript, 17 байт
Наконец, преобразование типов JavaScript может быть полезно! Обратите внимание, что это на самом деле будет выводить массив, но преобразование строки (помещение его в HTML) делает его списком, разделенным запятыми.
Если разделенные запятыми списки допустимы, то допустимо следующее:
7 байт
ПРИМЕЧАНИЕ: фрагмент по какой-то причине сломан
источник
["["]
... Я попытался запустить(a=>eval(
[$ {a}]))(["["])
и получилSyntaxError
oninput
событие только однимbutton
кликом.PHP, 73 байта
источник
Атташе , 14 байт
Попробуйте онлайн!
К счастью, в Attache есть оператор «векторизации», который применяет функцию к атомам списка. В этом случае все, что нам нужно сделать, это настроить жнец с
Reap
иSow
все атомы входа_
с@>
. Я думаю, что это довольно элегантно.альтернативы
15 байтов:
Fixpoint{`'^^_}
16 байтов:
Fixpoint!&Concat
17 байтов:
{q:=[]q&Push@>_q}
17 байтов:
Fixpoint[&Concat]
источник
Эликсир , 74 байта
Первый ответ Elixir, так что, возможно, можно немного поиграть в гольф.
Попробуйте онлайн.
Объяснение:
Конечно, если встроенные функции были разрешены, это могло бы быть 25 байтов вместо этого:
Попробуйте онлайн.
источник
Желе , 4 байта
Попробуйте онлайн!
объяснение
Встроенный
F
будет один байт, если это разрешено.источник
Wolfram Language (Mathematica) , 13 байт
Попробуйте онлайн!
Un-golfed:
F[x_] := Level[x, {-1}]
выбирает элементы структуры на последнем уровне ее древовидной формы . Я не уверен, что это считается «избегать встроенных» (что будет
Flatten
).источник