Рассмотрим массив A
длины n
. Массив содержит только натуральные числа. Например A = (1,1,2,2)
. Определим f(A)
как множество сумм всех непустых непрерывных подмассивовA
. В этом случае f(A) = {1,2,3,4,5,6}
. Шаги для производства f(A)
следующие:
Подмассивы A
есть (1), (1), (2), (2), (1,1), (1,2), (2,2), (1,1,2), (1,2,2), (1,1,2,2)
. Их соответствующие суммы 1,1,2,2,2,3,4,4,5,6
. Поэтому набор, который вы получаете из этого списка{1,2,3,4,5,6}
.
задача
Учитывая набор сумм, S
приведенных в отсортированном порядке, содержащих только натуральные числа и длину массива n
, ваша задача - вывести хотя бы один массив, X
такой что f(X) = S
.
Например, если S = {1,2,3,5,6}
и n = 3
тогда действительный вывод X = (1,2,3)
.
Если такого массива нет, X
ваш код должен вывести любое постоянное значение.
Примеры
Вход: n=4, S = (1, 3, 4, 5, 6, 8, 9, 10, 13)
возможный выход:X = (3, 5, 1, 4)
Вход: n=6, S = (2, 3, 4, 5, 7, 8, 9, 10, 12, 14, 17, 22)
возможный выход:X = (5, 3, 2, 2, 5, 5)
Вход: n=6, S = (2, 4, 6, 8, 10, 12, 16)
возможный выход:X = (4, 2, 2, 2, 2, 4)
Вход: n=6, S = (1, 2, 3, 4, 6, 7, 8, 10, 14)
возможный выход:X = (4, 2, 1, 1, 2, 4)
Вход: n=10, S = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 23, 24, 25)
возможный выход:X = (1, 1, 3, 1, 2, 1, 2, 5, 4, 5)
.
Входной сигнал: n=15, S = (1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31)
, возможно выход: X = (1, 2, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 2, 1, 3)
.
Формат ввода и вывода
Ваш код может принимать и выводить данные в любом удобном для человека формате. Однако, пожалуйста, покажите результаты тестирования на примерах в вопросе.
Продолжительность
Вы должны быть в состоянии выполнить код до завершения для всех примеров в вопросе. В принципе он должен быть верным n
, 15
но вам не нужно доказывать, что он будет достаточно быстрым для всех входных данных.
Ответы:
Шелуха , 20 байт
Попробуйте онлайн!
Возвращает одно решение или пустой список, если его не существует. Последний контрольный пример (
n=15
) заканчивается за 3,8 секунды на TIO.объяснение
Программа состоит из двух частей. В первой части (
¡
и справа от нее) мы создаем бесконечный список, чейk
элемент th является списком, содержащим всеk
списки длин, в которых находятся суммы срезовS
. Мы делаем это индуктивно, начиная с 1-элементных фрагментовS
и на каждом шаге добавляя каждый элементS
к каждому списку и сохраняя те, чьи суммы префиксов находятся вS
. Во второй части (!
и слева от нее) мы беремn
th-ый элемент списка, который содержит length-n
списки. Из них мы выбираем первый, чьи суммы срезов фактически содержат каждый элементS
.В коде давайте сначала заменим
o
иȯ
(которые объединяют две и три функции в одну) скобками для ясности.Есть некоторые части, которые требуют большего объяснения. В этой программе верхние индексы
⁰¹
ссылаются на первый аргументS
. Однако, еслиα
это функция, тоα¹
означает «применитьα
кS
», а⁰α
означает «подключитьсяS
ко второму аргументуα
». Функция¦
проверяет, содержит ли первый аргумент все элементы второго (с учетом кратностей), поэтомуS
должен быть и второй аргумент.В первой части используемую функцию
¡
можно интерпретировать какS(f~Λ€∫)(×:)¹
. КомбинаторS
ведет себя какSαβγ -> (αγ)(βγ)
, что означает, что мы можем упростить его(f~Λ€∫¹)(×:¹)
. Вторая часть×:¹
- это «смешать сS
добавлением», и ее результат передается первой части. Первая частьf~Λ€∫¹
, работает так. Функцияf
фильтрует список по условию, которое в данном случае является~Λ€∫¹
. Он получает список списковL
, поэтому мы имеем~Λ€∫¹L
. Комбинатор~
ведет себя так~αβγδε -> α(βδ)(γε)
: первый аргумент передаетсяβ
, второй -γ
и результаты объединяются сα
. Это значит, что у нас естьΛ(€¹)(∫L)
. Последняя часть∫L
- это просто кумулятивные суммыL
,€¹
это функция, которая проверяет членствоS
,Λ
принимает условие (здесь€¹
) и список (здесь∫L
) и проверяет, что все элементы удовлетворяют ему. Проще говоря, мы отфильтровываем результаты микширования по тому, вошли ли их кумулятивные суммыS
.источник
Рубин , 135 байт
Попробуйте онлайн!
Используйте поиск в ширину. n = 10 работает на TIO, n = 15 занимает больше минуты, но работает на моей машине.
Рубин , 147 байт
Попробуйте онлайн!
Оптимизированная версия, работает на TIO для n = 15 (~ 20 сек)
На самом деле, это начало подхода без грубой силы. Я надеюсь, что кто-то поработает над этим и найдет полное решение.
Первые идеи:
Что приводит нас к следующей оптимизации:
Рубин , 175 байт
Попробуйте онлайн!
~ 8,5 секунд на TIO. Неплохо...
... и так далее (будет реализовано)
источник
Haskell,
117111 байтов6 байтов сохранено благодаря @nimi!
Попробуйте онлайн!
f
r
i
n
s
Когда значение
n
равно нулю (поле для гольфаn<1
), список должен быть готов, поэтому мы проверяем, все ли значения были просмотрены. Если нет, мы возвращаем пустой список, чтобы указать отсутствие решений, иначе мы возвращаем одноэлементный список, содержащий пустой список, к которому будут добавлены выбранные элементы. Этот случай также мог бы быть обработан с помощью дополнительных уравненийЕсли
n
не ноль, мы возвращаемЭто список (1) списков, откуда берется первый элемент (2),
s
а остальные (5) - из рекурсивного вызова при условии (4), в котором находятся все новые суммыs
. Новые суммы вычисляются в (3) - заметка,t
взятая из одноэлементного списка, уродливая игра в гольф для того, что в идиоматическом Хаскеле было быlet t=y:map(y+)i
. Рекурсивный вызов (5) получает в качестве новогоr
набора старый набор без тех элементов, которые появляются среди новых суммt
.Основная функция
&
вызывает вспомогательную функцию, говоря, что нам все еще нужно увидеть все значения (r=s
) и что суммы еще не определены (i=[]
).Для еще семи байтов мы можем ограничить вычисление только первым результатом (если есть), который намного быстрее и обрабатывает все тестовые случаи менее чем за 2 секунды.
Попробуйте онлайн! (это только первый вариант вариации старой версии)
источник
map
, я только попробовал,<$>
но для этого потребовались дополнительные парены ... @ Ануш Я понятия не имею, что такое решение за полиномиальное времяЧисто , 177 байт
Попробуйте онлайн!
Занимает около 40 секунд на моей машине для
n=15
тестового случая, но время ожидания на TIO.Чисто , 297 байт
Попробуйте онлайн!
Этот включает в себя некоторые оптимизации, сделанные ГБ, а также некоторые из моих собственных. Я думаю, что некоторые из них можно сделать более общими, поэтому я добавлю объяснение, как только это будет сделано.
На моей машине это займет около 10 секунд, на TIO - 40 секунд.
источник
@mention
тобой завтра, когда они встанут, к сожалению, сегодня нет времени.Python 3 , 177 байт
Попробуйте онлайн!
(некоторые новые строки / пробелы добавлены, чтобы читателям не приходилось прокручивать код)
Прямой порт моего ответа Jelly (с некоторыми изменениями, см. Раздел «примечание» ниже)
Результат локального прогона:
Я слышал, что
itertools
это многословно, но моя лучшаяcombinations
реализация еще более многословна:Примечание .
a[p//n:p%n+1]
занимает в 2 раза больше времени, но экономит несколько байтов.combinations
возвращению итератора это более удобно для памяти.источник
Желе , 35 байт
Попробуйте онлайн!
Запускать локально: (n = 15 занимает более 1 ГБ ОЗУ)
(на самом деле я запустил версию в кодировке UTF8, которая занимает более 35 байт, но в любом случае результат тот же)
Это решение использует короткое замыкание, чтобы уменьшить время работы.
Без короткого замыкания этот код занимает примерно( | S| -2п - 2) ×( n36+ n2журналN2) операции, которая оценивает ( 26-215 - 2) ×( 1536+ 152журнал152) ≈5,79× 109 Однако из-за неэффективности Python и Jelly, это займет вечность, чтобы завершить. Благодаря короткому замыканию, оно может закончиться намного раньше.
объяснение
Отметим, что суммы всех непустых префиксов присутствуют во входных данных, и они строго растут. Также можно предположить, что самый большой и второй по величине элемент - это префиксная сумма.
Поэтому мы можем рассмотреть все способы выборап - 2 отдельные элементы от первого | S| -2 элементы (есть ( | S| -2п - 2) такие списки), вычислить последовательные различия, чтобы восстановить элементы; затем проверьте, действительно ли это наивно (получить всеN2 подмассивы, подсчитать сумму, uniquify. Общая длина подмассивов составляет околоN36 )
Не проверено (но должно иметь одинаковую производительность)
Желе , 32 байта
Попробуйте онлайн!
Более неэффективная версия (без короткого замыкания):
Желе , 27 байт
Попробуйте онлайн!
Для теста n = 15 он занимает до 2 ГБ ОЗУ и не завершается через ~ 37 минут.
примечание :
Ẇ§
может быть заменено наÄÐƤẎ
. Это может быть более эффективным.источник
APL (NARS), символы 758, байты 1516
Функция G в G x (с помощью функции H) найдет все перестановки x. Функция d в xdy находит, генерирует ли массив y после массива упражнения x возвращающее логическое значение. Функция F в x F y возвращает массив r длины x, так что ydr имеет значение true (= 1) Немного дольше, чем реализация, но именно она вычисляет весь случай в тесте за меньшее время ... Последний случай для n = 15 он запускается только за 20 секунд ... Я должен сказать, что это не находит много решений, возвращает только одно решение (наконец-то это кажется) за меньшее время (не исследованный тест для разных входов ...) 16 + 39 42 + + 8 + 11 + 11 + 18 + 24 + 24 + 54 + 11 + 12 + 7 + 45 + 79 + 69 + 12 + 38 + 26 + 72 + 79 + 27 + 15 + 6 + 13 (758)
источник