У меня есть куча чистых носков, которые я хочу разбить на пары. К сожалению, я могу брать только носки с любого конца кучи, а не с середины. Кроме того, я могу удалить носки из кучи только соответствующей пары одновременно. Моя стратегия состоит в том, чтобы сначала разбить кучу на одну или несколько меньших куч. Я думаю, что некоторые примеры прояснят это. Я буду представлять каждый носок как положительное целое число (совпадающие целые числа обозначают равные носки).
Если начальная куча носков
1 2 3 3 2 1
тогда мне не нужно делать никакого разделения. Я могу снять оба 1
носка, затем оба 2
носка, затем оба 3
носка.
Если вместо этого начальная куча
1 2 3 2 3 1
затем я должен сначала разделить его, потому что я не смогу соединить все носки, просто сняв их с конца. Одна возможность состоит в том, чтобы разделить это на две груды
1 2 3 and 2 3 1
Теперь я могу снять 1
носки, уйти 2 3 and 2 3
, затем 3
носки, уйти 2 and 2
и, наконец, 2
носки.
Твоя работа
Учитывая начальную кучу носков, напишите программу, которая разделит ее на более мелкие, что позволит мне сортировать носки. Ваша программа должна разбить кучу на наименьшее количество возможных куч (если есть несколько лучших решений, вам нужно найти только одну).
Входные данные будут представлены в виде списка, строки с разделителями или другой удобной формы. Он будет содержать только целые числа между 1
и некоторым максимальным значением n
, причем каждое целое число встречается ровно дважды.
Вывод должен состоять из входного списка, разбитого на меньшие списки, представленные в любой удобной форме.
Примеры
Input Sample Output
1 1 1 1
1 2 1 2 1; 2 1 2
1 3 2 4 3 2 1 4 1 3 2; 4 3 2 1 4
1 2 3 4 3 4 1 2 1; 2 3; 4 3 4 1 2
1 1 2 2 3 3 1 1 2; 2 3 3
4 3 4 2 2 1 1 3 4 3 4 2; 2 1 1 3
Обратите внимание, что это не единственный допустимый выход для большинства из этих входов. Для второго случая, например, выходы 1 2; 1 2
или 1 2 1; 2
также будут приняты.
Спасибо Sp3000 за некоторые предложения по тестированию!
Я ненавижу тратить много времени на сортировку моей одежды, поэтому сделайте ваш код максимально коротким. Кратчайший ответ в байтах побеждает!
Заметки
- Я не хочу смотреть за носком, чтобы увидеть, есть ли у него соответствующая пара, поэтому брать оба носка в паре с одного конца нельзя. Например, если куча есть,
1 1 2 2
то вы не сможете оставить ее как одну кучу и взять оба1
носка с левого конца.
123213
можно разделить на1; 23; 213
(1; 23; 213
->1; 2; 21
->; 2; 2
)?123213
используя только две стопки, ваш ответ должен будет дать одну из двухсоставных.Ответы:
Pyth, 25 байт
Тестирование
Объяснение:
источник
JavaScript (ES6), 329
Непростая задача для языка, в котором нет встроенных комбинаторных функций.
Вероятно, чуть более пригодный для игры в гольф.
Примечание: все разделы имеют размер не менее 2, так как раздел с одним элементом всегда менее полезен.
Пояснение по частям
(это слишком многословно, но мне было сложно объяснить - в конце концов пропустить, чтобы «собрать все вместе»)
Рекурсивная функция для перечисления всех возможных разбиений массива
Теперь мне нужны разделы размером 2 или больше, поэтому я должен использовать эту функцию со слегка различными параметрами. Параметр v равен «размер массива - количество желаемых разделов - 1». Тогда я должен построить разделы немного по-другому.
Итак, я могу перечислить список разделов без разделения, 1 разделения, 2 разделения и так далее. Когда я найду рабочий раздел, я остановлюсь и выведу найденный результат.
Чтобы проверить, просканируйте список разделов, запишите значения в начале и в конце каждого из них, если найдено повторяющееся значение, затем удалите его. Повторяйте до тех пор, пока ничего не будет удалено, наконец: если все пары были удалены, этот раздел хорош.
Затем недостающая часть - это просто цикл, вызывающий функцию G, увеличивающую количество разделов. Выход из цикла, когда результат найден.
Поставить все это вместе
Тест
источник