Фон
Я был вдохновлен недавним видео 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]]
. Я правильно понимаю спецификацию?