Вызов
Ваша задача для этого вопроса - разбить входной массив целых чисел на второе вхождение каждого целого числа в этом массиве.
Недостаточно ясно? Вот пример, чтобы помочь
Входной массив:
[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5]
Выход:
[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]
Объяснение:
Вот массив с только вторым элементом, выделенным жирным шрифтом:
[2 1 1 2 3 2 2 4 5 6 7 3 7 0 5 ]
Теперь мы помещаем блоки массива разделения вокруг этих жирных секунд:
[2 1] 1 [] 2 [3 2 2 4 5 6 7] 3 [] 7 [0] 5 []
и обернуть эти разделенные массивы в массиве, чтобы получить окончательный
[[2 1] [] [3 2 2 4 5 6 7] [] [0] []]
Обратите внимание, что при возникновении смежных вторых вхождений будут пустые массивы.
правила
Как обычно, вы должны написать полную программу или функцию, принимающую входной массив через STDIN, ARGV или аргумент функции.
вход
Входные данные состоят из любого удобного массива (или похожего на массив) формата целых чисел.
Например, любое из следующего было бы приемлемо:
2 1 1 1 4 5 6
[2 1 1 1 4 5 6]
[2, 1, 1, 1, 4, 5, 6]
Выход
При выводе в STDOUT, ваш массив также может быть напечатан в любом удобном (вложенном) формате массива, например, в одном из
[[2 1] [1 4 5 6]]
[[2, 1], [1, 4, 5, 6]]
{{2, 1}, {1, 4, 5, 6}}
(Обычно это будет собственное строковое представление массивов на вашем языке.)
Также обратите внимание, что конечные пустые массивы должны быть напечатаны как часть массива.
счет
Это код-гольф, поэтому выиграй самый короткий код в байтах!
""
как пустой массив? Это пахнет фаворитом к определенному языку игры в гольф.2 1, 1 4 5 6
?Ответы:
APL 25
Пример:
Старый:
Это хороший вопрос для ключевого оператора (⌸), который был представлен в Dyalog APL v14. Он принимает функцию левого аргумента ({1 ↑ 1 ↓ ⍵}) и дает ее для каждого уникального аргумента индексы в векторе для этого аргумента. Здесь я беру второй индекс, затем проверяю, какой из индексов присутствует в этом списке ((⍳⍴⍵) ∊), и использую полученное логическое значение для расщепления исходного вектора.
Можно попробовать онлайн здесь:
http://tryapl.org
источник
1↓¨{1,∨⌿<\2=+\∘.=⍨⍵}⊂1∘,
APL (Dyalog 14) (31)
Это функция, которая принимает массив и возвращает вложенный массив.
Тестовое задание:
Объяснение:
0,⍵
: Добавить0
в начало⍵
, для облегчения обработки. (Это не считается случаем.)(
...)⊂
: Разделить массив в соответствии с заданной битовой маской. Новая группа начинается с каждого1
в битовой маске.+\∘.=⍨⍵
: для каждого значения в (оригинале)⍵
найдите все вхождения в⍵
. Затем составьте промежуточную сумму для каждого значения, указав квадратную матрицу для каждой позиции в⍵
сколько из каждого значения уже произошло.↓
: Разделить матрицу по ее строкам, указав для каждого значения массив, показывающий, сколько раз он встречался в каждой позиции.2⍳⍨¨
: В каждом из этих массивов найдите индекс первого2
.(⍳⍴⍵)∊
: Для каждого возможного индекса в⍵
посмотрите, содержится ли он в списке индексов второго вхождения. (Они начинают каждую группу, кроме первой.)1,
: Добавьте1
перед, отмечая начало первой группы.1↓¨
: Удалить первый элемент из каждой группы. (Это добавленное0
и второе вхождение каждого значения.)источник
J,
2824 символаОтдельное спасибо рандоме .
Это работает так. По всем префиксам (
\
) входного массива мы смотрим, сколько (+/@
) элементов префикса равно последнему элементу (={:
) этого префикса. Когда это число равно 2, мы знаем, что это второе вхождение этого элемента в массиве, поэтому мы разбиваем массив там, используя<;._1
.Старая вещь, используя уловки сортировки
(1&,<;._1~1,1=i.~(]-{)/:@/:)
.источник
(1&,<;._1~1,2=+/@(={:)\)
на 4 байта короче и намного проще. (/:@/:
это хороший трюк.)Mathematica,
585149 байтЭто безымянная функция, которая принимает список как
и возвращает вложенный список, как
Как это устроено
Это использует довольно неясную магию с
SplitBy
.Я отслеживаю вхождения каждого числа в функцию
f
. В Mathematica вы можете определить значение функции для каждого входа отдельно, и вам не нужно указывать значение для всех возможных входов (это больше похоже на хеш-таблицу на стероидах).Поэтому я начинаю с инициализации
f
0 для значений, которые присутствуют во входных данных с помощью(f@#=0;#)&/@
.Теперь
SplitBy
берет список и функцию и «разбивает список на подсписки, состоящие из последовательностей последовательных элементов, которые приf
применении применяются одно и то же значение » (обратите внимание, чтоSplitBy
ни один элемент не удаляется ). Но (недокументированный) подвох заключается в том, что онf
вызывается дважды для каждого элемента - при сравнении его с предшественником и его преемником. Так что если мы сделаеммы не просто получаем каждый номер один раз, но вместо этого это печатает
что составляет 6 звонков для 3 сравнений.
Мы можем разделить список перед каждым вторым вхождением, если напишем функцию, которая всегда возвращает,
False
но возвращает,True
когда второе вхождение сравнивается с элементом перед ним. Это третья проверка для этого элемента (две проверки для первого экземпляра плюс первая проверка для второго экземпляра). Следовательно, мы используем++f[#]==3&
. Приятно то, что это уже возвращаетсяFalse
снова при второй проверке второго вхождения, так что я могу вернутьсяTrue
для последовательных вторых вхождений, но все же разделить их . Аналогично, это не будет разделяться после второго вхождения, потому что функция уже возвращаетсяFalse
снова при второй проверке.Теперь вопрос требует, чтобы мы также удалили эти вторые вхождения, поэтому мы удаляем первый элемент из каждого списка с помощью
Rest/@
. Но, конечно, мы не хотим удалять самый первый элемент во входных данных, поэтому мы фактически начинаем с добавления элементаa
в начало списка с помощью{a}~Join~#
.a
является неопределенной переменной, которую Mathematica рассматривает как неизвестную, поэтому она не влияет на другие значенияf
. Это также гарантирует, что первый фактический элемент на входе получает две проверки, как и любой другой элемент.источник
Boole
там.Python, 148 байт
Довольно ужасное решение. Должен быть лучший способ ...
Позвони с
s([2, 1, 1, 1, 4, 5, 6])
.Неуправляемая версия
источник
Хаскелл,
11511310688это хранит количество каждого элемента в зависимости от количества элементов, что является интересным трюком.
это работает с использованием
%
функции, которая дала функцию f и аргумент,x
возвращает новую функцию, которая возвращаетf
примененную к ее аргументу, если она отличается отx
, и в1 + f x
противном случае.например,
3 % const 0
это функция, которая возвращает 0 для каждого аргумента, кроме 3, для которого она возвращает 1. update: объединяет,foldl
чтобы получить гораздо меньшую программу.источник
Ruby 66 demo
Ruby stabby lambda, который принимает массив в качестве параметра и возвращает массив массивов.
источник
Питон: 100 байт
Простое решение. Я перебираю список, подсчитываю, сколько раз символ появлялся раньше, и добавляю деталь с момента последней проверки в список вывода.
источник
Руби, 66
объяснение
e
хэш счетчиков вхождений для каждого элемента,r
Массив, в котором хранится результат.1
.2
, мы должны разделить. Добавьте пустоеArray
к результату.Array
результату.источник
CJam,
2524 байтаПринимает участие от STDIN как
и результаты как
Я в основном перебираю все элементы массива, один за другим помещая их в другой массив. Затем я получаю счет текущего элемента в другом массиве. Если его 2, я запускаю другой массив из этого места. Этот вид случайного запуска массива может быть достигнут только на языке стека.
Расширение кода :
Попробуйте онлайн здесь
1 байт сохранен из чаевых Мартина в чате
источник
Рубин, 64 байта
источник
Perl 5: 36
Не уверен, что это приемлемо, так как здесь нет фактического разделения.
Пример:
источник
-pa
как два дополнительных байта (потому что это «стоит» только два байта, так как вы можете записать это-pae
вместо-e
). Так что было бы 38, а не 36.CJam, 28 байт
Принимает участие как STDIN
и печатает вывод в STDOUT как
Обратите внимание , что пустые строки и пустые массивы одно и то же в CJam и отображаются
""
по умолчанию (это является родным представлением пустых массивов).(Я начал работать над этим немного раньше, чем было объявлено о проблеме, потому что мы обсуждали, насколько сложной будет эта задача.)
объяснение
По сути, я дублирую каждый элемент в массиве, если только это не второе вхождение, в этом случае я заменяю первую копию пробелом. По соображениям игры в гольф этот модифицированный массив построен в обратном порядке. Так
[2 1 1 2 3 2 3]
становитсяЗатем я выбираю каждый второй элемент с конца, который является исходным массивом, но со вторыми вхождениями, замененными пробелами, т.е.
Наконец, я просто разбил массив на пробелы. Вот разбивка кода:
источник
""
явно разрешено в первой редакции вопроса. Текущая редакция гласит: «Любой удобный формат ... обычно собственное представление строк в массивах».Инструменты Unix, 100 байт
Исключает ввод через стандартный ввод. Это в основном просто заменяет каждое второе вхождение
"] ["
. Не работает с пустыми строками,[]
выдаст пустую строку, что я считаю удобным представлением пустого массива :)источник
11
? это будет преобразовано в1][
?APL, 42 символа
Пример:
Выход:
Проверено здесь.
Если я должен вывести строку, которая интерпретируется точно как правильная структура в APL ... 49 символов
источник
1↓1
решение проблемы решит проблему, но это выглядит слишком странно.Ява, 223
Это работает только в Oracle или OpenJDK JRE, так как я использую эту причуду в их реализации квантификатора и проверки длины в поиске для реализации просмотра переменной длины.
Большая часть работы выполняется в регулярном выражении, которое показано ниже в необработанном виде:
Прежде чем мы рассмотрим приведенное выше регулярное выражение, давайте рассмотрим эквивалентное регулярное выражение .NET, которое проще, поскольку оно напрямую поддерживает просмотр переменной длины (поиск в .NET, скорее всего, выполняется в режиме сопоставления справа налево) :
*\b(\d+)\b
и*
в конце соответствует число и окружающие пробелы (если есть). Связанные проверки должны предотвращать совпадение частичного числа, поскольку пробелы с обеих сторон являются необязательными. Он также фиксирует число, чтобы проверить, является ли оно вторым появлением в массиве.(?<=(.*\b\1\b){2})
проверяет, что 2 экземпляра числа, захваченного выше, могут быть найдены.(?<!(.*\b\1\b){3})
проверяет, что не может быть найдено 3 экземпляра захваченного числа. Оба условия в совокупности утверждают, что пока существует только 2 экземпляра числа. Связанные проверки предназначены для проверки всего числа.Вернуться к версии Java. Для реализации переменной длины мы трансформируем
в
Я немного помахал рукой в связи с тем, что
.
исключаются разделители строк, но это можно легко исправить, и я не хочу дополнительно усложнять синтаксис.Предварительный просмотр всегда равен 0 в длине, и проверка длины проходит благодаря реализации
*
квантификатора.^
не обязательно, чтобы заставить его работать, но оно есть, чтобы сбойный случай не удался быстрее. Просмотр в реализации Oracle / OpenJDK выполняется путем возврата назад к минимальной длине шаблона, затем сопоставления, затем промывания и повторения путем увеличения длины до тех пор, пока не будет найдено совпадение или, в худшем случае, до максимальной длины шаблона. , С^
я проверяю, совпадает ли строка префикса только один раз.Тем не менее, упреждающий просмотр внутри упреждающего просмотра не ограничен правой границей предварительного просмотра, поэтому он может совпадать до конца строки. Чтобы утвердить границу, я фиксирую оставшуюся часть строки в другой группе захвата в перспективе и использую ее, чтобы ограничить правление шаблона переменной длины.
Поскольку мой шаблон уже начинается с
.*
, мне не нужно добавлять еще один.*
перед.источник
Perl 108
В бою:
Примечание: две первые строки
$Data::...
предназначены только для более приятного представления, а третья строка@a=@b=@e=();
предназначена для того, чтобы инструмент работал на нескольких строках.источник
R, 76
Выходные данные для примера: список из пяти элементов, включая три пустых вектора. (
numeric(0)
).Кстати: код генерирует предупреждающее сообщение, которое можно игнорировать.
источник
awk 29
Это занимает немного свободы с форматами ввода и вывода. Ввод "массив" является вертикальным, по одному числу в строке. Вывод также вертикальный, по одному на строку, с тире, разделяющими массивы.
Входные данные:
Выход:
источник
Pyth 30
32Я впервые экспериментирую с Пифом. Это то же решение, что и в моем решении Python.
Вы можете попробовать это онлайн: Pyth Compiler / Executor
Например, вход
распечатает
Объяснение:
источник
=Y+Y...
?~Y...
Python 2, 84
Список
l
пока является выходным. Перебираем элементы. Если текущим является второе появление, мы начинаем новый пустой подсписок; в противном случае мы добавим его в последний список. Список элементов, которые мы видели, хранится вp
. Как ни странно, восстановление списка кажется короче, чем разрезание ввода.источник
Чистый Баш
1119481 только для расщепления:
Вторая строка
declare -p c
просто сбрасывает переменнуюОбразец:
Примечание: строка
local b c d i
требуется только для запуска функции несколько раз.За самую сексуальную презентацию (+26)
Будет что-то вроде:
источник
Скала,
122111Возьмите набор символов, напечатайте в виде
[21][][3224567][][0][]
,122111:... или взять коллекцию символов и вернуть вложенные списки,
135129:Я уверен, что есть некоторые сбережения, которые я мог бы получить, я не смотрел слишком усердно.
источник
Python 220 байт
Ниже 220 байтов, что не очень хорошо по сравнению со многими другими, но работает достаточно быстро с большими целыми числами!
источник
=
, изменениеxlist
иresult
в более короткие имена, и удалить пробелы вокруг==
,;
и:
. Если вам нужна дополнительная помощь, просто введите@NoOneIsHere
(или любое имя пользователя), и я / пользователь попытается помочь.Java: 563 байта
обратите внимание, что для этого используется Java 8, pre-JDK8 будет на несколько байтов длиннее из-за foreach.
источник
Integer.MAX_VALUE
в2147483647
? Это то же значение с меньшим количеством байтов. Кроме того,IndexOutOfBoundsException
может быть сокращено доException