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