Фон
Я был вдохновлен недавним видео 3Blue1Brown о проблеме расщепления ожерелья (или, как он это называет, о проблеме украденного ожерелья) и ее связи с теоремой Борсука-Улама .
В этой задаче два вора украли ценное ожерелье, состоящее из нескольких разных видов драгоценных камней. Существует четное количество каждого типа драгоценного камня, и воры хотят разделить каждый тип драгоценного камня равномерно между ними. Загвоздка в том, что они должны сделать это, разбив ожерелье на некоторое количество смежных сегментов и распределив сегменты между ними.
Ниже приведен пример с четырьмя типами драгоценностей , обозначенных S
, E
, D
и R
(для сапфир, изумруд, алмаз, рубин и, соответственно). Допустим, ожерелье выглядит следующим образом:
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
Есть 8
сапфиры, 10
изумруды, 4
бриллианты и 6
рубины. Мы можем разделить ожерелье следующим образом:
[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
Затем, если мы передадим первый, третий и пятый сегменты одному вору, а второй и четвертый сегменты - другому вору, каждый из них получит 4
сапфиры, 5
изумруды, 2
бриллианты и 3
рубины:
[S], [S,E,S,D,E,R,S], [R,R,D,E,E,E]
[S], [R,E,S,S,S,D,R,E,E,R,E,D,E],
Используя 0
-indexing, эти сокращения происходят по индексам [1,2,9,22]
.
Цель
Оказывается, что такое справедливое разделение всегда можно сделать, используя самое большее количество n
вырезов, где n
указано количество типов драгоценных камней. Ваша задача - написать полную программу или функцию, которая принимает ожерелье в качестве входных данных и выдает минимальное такое деление (наименьшее количество сокращений).
вход
Ввод может быть в любом удобном формате. Ожерелье должно быть последовательностью драгоценных камней и ничего более; например, список целых чисел, словарь с ключами, представляющими типы драгоценных камней, и значения, являющиеся списками индексов. При желании вы можете указать длину ожерелья или количество различных типов драгоценных камней, но вы не должны принимать никаких других данных.
Вы можете предположить, что входное ожерелье является действительным. Вам не нужно обрабатывать случай, когда есть нечетное количество драгоценных камней данного типа или ожерелье пусто.
Выход
Опять же, вывод может быть в любом удобном формате; например, список сегментов, список позиций выреза, словарь с ключами, представляющими двух воров, и значениями, являющимися списками сегментов, и т.д. Сегменты могут быть представлены их начальным индексом, конечным индексом, списком последовательных индексов, списком драгоценных камней, их длина и т. д. Вы можете использовать 0
или 1
индексировать. Если порядок не имеет значения для вашего формата, то ваш вывод может быть в любом порядке. Вот вышеупомянутый вывод в нескольких различных форматах:
list of segments: [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
list of cuts: [1,2,9,22]
list of lengths: [1,1,7,13,6]
dictionary: {'thief1' : [(R,R,D,E,E,E),(S),(S,E,S,D,E,R,S)], 'thief2' : [(S),(R,E,S,S,S,D,R,E,E,R,E,D,E)]}
Обратите внимание, что порядок важен в списке сегментов (сегменты чередуются между ворами) и списке длин (для идентификации сегментов), но не в списке разрезов или словаре. Редактировать: Грег Мартин указал, что это не будет действительным выходом, так как справедливое деление может быть получено в два разреза
Контрольные примеры
[1,2,1,2,1,3,1,3,3,2,2,3] -> [[1,2,1],[2,1,3,1],[3,3,2],[2,3]]
[1,1,1,1,2,2,3,3,3,3,3,3] -> [[1,1],[1,1,2],[2,3,3,3],[3,3,3]]
[1,1,1,1,1,1,1,1,1,1,1,1] -> [[1,1,1,1,1,1],[1,1,1,1,1,1]]
[1,1,1,1,2,3,4,2,3,4,2,2] -> [[1,1],[1,1,2,3,4,2],[3,4,2,2]]
Примечания
- Стандартные лазейки запрещены.
- Это код-гольф ; кратчайший ответ (в байтах) выигрывает.
источник
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
кажется, что вывод должен быть[[S,S,S,E,S,D,E,R],[S,R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
, так как это имеет меньше сокращений, чем[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
. Я правильно понимаю спецификацию?Ответы:
Брахилог , 13 байт
Попробуйте онлайн!
Примечание: метапредикат
ᵛ
новее этой задачи.объяснение
Разделы нумеруются в порядке возрастания количества блоков, поэтому в результате будет получено как можно меньше блоков.
источник
Желе , 18 байт
Попробуйте онлайн!
Не эффективно - пример имеет 28 драгоценных камней , которые не будут работать без огромных ресурсов , так как первый шаг этой реализации было бы построить список из 2 27 возможных разбиений.
Возвращает список списков - сегменты для того, чтобы разделить их между альтернативными ворами. (Относительно вывода TIO: когда список содержит только один элемент, неявная печать не затрагивает скобки,
[]
)Как?
источник
Mathematica, 118 байт
Почти победил желе ... только 1;)
Чистая функция, принимающая три аргумента: ожерелье, как список токенов, таких как
{A, A, A, A, B, C, D, B, C, D, B, B}
; длина ожерелья; и количество отдельных драгоценностей раз. Возвращает список подсписков в форме{{A, A}, {-A, -A, -B, -C, -D, -B}, {C, D, B, B}}
, в которой токены без отрицательных знаков идут одному вору, а токены с отрицательными знаками - другому вору. (Хотя это избыточная информация, алгоритм приводит к такому представлению, и удаление отрицательных знаков будет стоить несколько байтов.)Сначала мы должны реализовать функцию, которая принимает список и набор
n
вырезок и возвращает списокn+1
вложенных списков, полученных путем вырезания входного списка в этихn
вырезанных местах; двоичный инфиксный оператор±
используется для этой цели и рекурсивно определяется черезl_±c_:=Append[-#±Most@c,#2]&@@l~TakeDrop~Last@c;l_±{}:={l};
. Из-за отрицательного знака сразу послеAppend
этого, в списках поочередно есть отрицательные знаки, прикрепленные к каждому токену.Затем мы генерируем все возможные наборы вырезов, длина которых не превышает количество типов драгоценных камней, используя
Range@#2~Subsets~#3
иi=#;(i±#)&/@
применяя±
оператор (с входным списком драгоценных камней) к каждому из этих наборов вырезов по очереди.Наконец,
SelectFirst[...,Tr[Tr/@#]==0&]&
выбирает первое из полученных делений ожерелья, которое справедливо. Это достигается путем буквального суммирования всех элементов во всех подсписках; Mathematica достаточно мудра, чтобы отменить положительные и отрицательные копии каждого токена очевидным образом.источник
Pyth, 16 байт
Попробуйте онлайн: демонстрация или тестовый набор
Объяснение:
источник
05AB1E , 14 байтов
Попробуйте онлайн или проверьте все контрольные примеры .
Объяснение:
источник