Перечисление разделов с минимальным количеством подмножеств, так что все, кроме не более одного подмножества, имеют размер не более M
.
Приведенный ниже код выполняет следующее:
При заданном спискеотдельные элементы и некоторый размер M
, он перечисляет все разделы типа List[List[Int]]
, такие что:
- каждое подмножество раздела (представленное
List[Int]
) содержит не более M
элементов - количество подмножеств минимально
- существует не более одного подмножества с менее чем
M
элементов
То есть (почти) все подмножества имеют размер M
, самое большее с одним исключением.Тогда исключение имеет размер N % M
, где N
- количество элементов в исходном списке.
Решение
Получилосьбыть не совсем тривиальным.Особенно тот факт, что размер подмножеств не должен делить количество элементов, был неприятен, потому что это нарушило симметрию еще одним способом.
Вот решение, состоящее из трех этапов:
- Решить проблему для случая, когда размер разделов делит размер списка (
sameSizePartitions
) - Решить более общую проблему генерации разделов произвольных заданных размеров (
prescribedSizePartition
) - Подставляем тонкую оболочку
maxSizePartitions
, которая вычисляет предписанные размеры и вызывает prescribedSizePartition
.
Итак, было: сначала обобщите, решите другой особый случай, используйте другой особый случай дляРешите общий случай, используйте общий случай для реализации желаемой функции.
Вот как это выглядит:
type Partition = List[List[Int]]
def sameSizePartitions(elems: List[Int], partSize: Int): List[Partition] = {
def recHelper(unused: List[Int]): List[Partition] = {
if (unused.size <= partSize) {
List(List(unused))
} else {
val h :: t = unused
(for {
combination <- t.combinations(partSize - 1)
tail <- recHelper(t filterNot combination.contains)
} yield (h :: combination) :: tail).toList
}
}
recHelper(elems)
}
/**
* @param elems list with unique elements
* @param sizes map (size -> numberOfPartitionsWithThisSize)
*/
def prescribedSizePartitions(elems: List[Int], sizes: Map[Int, Int]): List[Partition] = {
if (sizes.isEmpty) {
if (elems.isEmpty) List(Nil)
else throw new IllegalArgumentException("sizes empty, but elems = " + elems)
} else {
val (size, numberOfPartitions) = sizes.head
val numElementsNeededForPartitionsOfThisSize = size * numberOfPartitions
for {
elemSelection <- elems.combinations(numElementsNeededForPartitionsOfThisSize).toList
tailPartition <- prescribedSizePartitions(elems.filterNot(elemSelection.contains), sizes - size)
currSizePart <- sameSizePartitions(elemSelection, size)
} yield currSizePart ++ tailPartition
}
}
def maxSizePartitions(elems: List[Int], maxSize: Int): List[Partition] = {
val n = elems.size
val ofMaxSize = n / maxSize
val restSize = n % maxSize
if (restSize == 0) {
sameSizePartitions(elems, maxSize)
} else {
prescribedSizePartitions(elems, Map(maxSize -> ofMaxSize, restSize -> 1))
}
}
Примеры:
maxSizePartitions((1 to 4).toList, 2) foreach println
maxSizePartitions((1 to 5).toList, 3) foreach println
maxSizePartitions((1 to 8).toList, 3) foreach println
Вывод:
List(List(1, 2), List(3, 4))
List(List(1, 3), List(2, 4))
List(List(1, 4), List(2, 3))
List(List(1, 2, 3), List(4, 5))
List(List(1, 2, 4), List(3, 5))
List(List(1, 2, 5), List(3, 4))
List(List(1, 3, 4), List(2, 5))
List(List(1, 3, 5), List(2, 4))
List(List(1, 4, 5), List(2, 3))
List(List(2, 3, 4), List(1, 5))
List(List(2, 3, 5), List(1, 4))
List(List(2, 4, 5), List(1, 3))
List(List(3, 4, 5), List(1, 2))
List(List(1, 2, 3), List(4, 5, 6), List(7, 8))
List(List(1, 2, 4), List(3, 5, 6), List(7, 8))
List(List(1, 2, 5), List(3, 4, 6), List(7, 8))
List(List(1, 2, 6), List(3, 4, 5), List(7, 8))
List(List(1, 3, 4), List(2, 5, 6), List(7, 8))
List(List(1, 3, 5), List(2, 4, 6), List(7, 8))
List(List(1, 3, 6), List(2, 4, 5), List(7, 8))
List(List(1, 4, 5), List(2, 3, 6), List(7, 8))
List(List(1, 4, 6), List(2, 3, 5), List(7, 8))
List(List(1, 5, 6), List(2, 3, 4), List(7, 8))
List(List(1, 2, 3), List(4, 5, 7), List(6, 8))
List(List(1, 2, 4), List(3, 5, 7), List(6, 8))
List(List(1, 2, 5), List(3, 4, 7), List(6, 8))
List(List(1, 2, 7), List(3, 4, 5), List(6, 8))
List(List(1, 3, 4), List(2, 5, 7), List(6, 8))
List(List(1, 3, 5), List(2, 4, 7), List(6, 8))
List(List(1, 3, 7), List(2, 4, 5), List(6, 8))
List(List(1, 4, 5), List(2, 3, 7), List(6, 8))
List(List(1, 4, 7), List(2, 3, 5), List(6, 8))
List(List(1, 5, 7), List(2, 3, 4), List(6, 8))
List(List(1, 2, 3), List(4, 5, 8), List(6, 7))
List(List(1, 2, 4), List(3, 5, 8), List(6, 7))
List(List(1, 2, 5), List(3, 4, 8), List(6, 7))
List(List(1, 2, 8), List(3, 4, 5), List(6, 7))
List(List(1, 3, 4), List(2, 5, 8), List(6, 7))
List(List(1, 3, 5), List(2, 4, 8), List(6, 7))
List(List(1, 3, 8), List(2, 4, 5), List(6, 7))
List(List(1, 4, 5), List(2, 3, 8), List(6, 7))
List(List(1, 4, 8), List(2, 3, 5), List(6, 7))
List(List(1, 5, 8), List(2, 3, 4), List(6, 7))
List(List(1, 2, 3), List(4, 6, 7), List(5, 8))
List(List(1, 2, 4), List(3, 6, 7), List(5, 8))
List(List(1, 2, 6), List(3, 4, 7), List(5, 8))
List(List(1, 2, 7), List(3, 4, 6), List(5, 8))
List(List(1, 3, 4), List(2, 6, 7), List(5, 8))
List(List(1, 3, 6), List(2, 4, 7), List(5, 8))
List(List(1, 3, 7), List(2, 4, 6), List(5, 8))
List(List(1, 4, 6), List(2, 3, 7), List(5, 8))
List(List(1, 4, 7), List(2, 3, 6), List(5, 8))
List(List(1, 6, 7), List(2, 3, 4), List(5, 8))
List(List(1, 2, 3), List(4, 6, 8), List(5, 7))
List(List(1, 2, 4), List(3, 6, 8), List(5, 7))
List(List(1, 2, 6), List(3, 4, 8), List(5, 7))
List(List(1, 2, 8), List(3, 4, 6), List(5, 7))
List(List(1, 3, 4), List(2, 6, 8), List(5, 7))
List(List(1, 3, 6), List(2, 4, 8), List(5, 7))
List(List(1, 3, 8), List(2, 4, 6), List(5, 7))
List(List(1, 4, 6), List(2, 3, 8), List(5, 7))
List(List(1, 4, 8), List(2, 3, 6), List(5, 7))
List(List(1, 6, 8), List(2, 3, 4), List(5, 7))
List(List(1, 2, 3), List(4, 7, 8), List(5, 6))
List(List(1, 2, 4), List(3, 7, 8), List(5, 6))
List(List(1, 2, 7), List(3, 4, 8), List(5, 6))
List(List(1, 2, 8), List(3, 4, 7), List(5, 6))
List(List(1, 3, 4), List(2, 7, 8), List(5, 6))
List(List(1, 3, 7), List(2, 4, 8), List(5, 6))
List(List(1, 3, 8), List(2, 4, 7), List(5, 6))
List(List(1, 4, 7), List(2, 3, 8), List(5, 6))
List(List(1, 4, 8), List(2, 3, 7), List(5, 6))
List(List(1, 7, 8), List(2, 3, 4), List(5, 6))
List(List(1, 2, 3), List(5, 6, 7), List(4, 8))
List(List(1, 2, 5), List(3, 6, 7), List(4, 8))
List(List(1, 2, 6), List(3, 5, 7), List(4, 8))
List(List(1, 2, 7), List(3, 5, 6), List(4, 8))
List(List(1, 3, 5), List(2, 6, 7), List(4, 8))
List(List(1, 3, 6), List(2, 5, 7), List(4, 8))
List(List(1, 3, 7), List(2, 5, 6), List(4, 8))
List(List(1, 5, 6), List(2, 3, 7), List(4, 8))
List(List(1, 5, 7), List(2, 3, 6), List(4, 8))
List(List(1, 6, 7), List(2, 3, 5), List(4, 8))
List(List(1, 2, 3), List(5, 6, 8), List(4, 7))
List(List(1, 2, 5), List(3, 6, 8), List(4, 7))
List(List(1, 2, 6), List(3, 5, 8), List(4, 7))
List(List(1, 2, 8), List(3, 5, 6), List(4, 7))
List(List(1, 3, 5), List(2, 6, 8), List(4, 7))
List(List(1, 3, 6), List(2, 5, 8), List(4, 7))
List(List(1, 3, 8), List(2, 5, 6), List(4, 7))
List(List(1, 5, 6), List(2, 3, 8), List(4, 7))
List(List(1, 5, 8), List(2, 3, 6), List(4, 7))
List(List(1, 6, 8), List(2, 3, 5), List(4, 7))
List(List(1, 2, 3), List(5, 7, 8), List(4, 6))
List(List(1, 2, 5), List(3, 7, 8), List(4, 6))
List(List(1, 2, 7), List(3, 5, 8), List(4, 6))
List(List(1, 2, 8), List(3, 5, 7), List(4, 6))
List(List(1, 3, 5), List(2, 7, 8), List(4, 6))
List(List(1, 3, 7), List(2, 5, 8), List(4, 6))
List(List(1, 3, 8), List(2, 5, 7), List(4, 6))
List(List(1, 5, 7), List(2, 3, 8), List(4, 6))
List(List(1, 5, 8), List(2, 3, 7), List(4, 6))
List(List(1, 7, 8), List(2, 3, 5), List(4, 6))
List(List(1, 2, 3), List(6, 7, 8), List(4, 5))
List(List(1, 2, 6), List(3, 7, 8), List(4, 5))
List(List(1, 2, 7), List(3, 6, 8), List(4, 5))
List(List(1, 2, 8), List(3, 6, 7), List(4, 5))
List(List(1, 3, 6), List(2, 7, 8), List(4, 5))
List(List(1, 3, 7), List(2, 6, 8), List(4, 5))
List(List(1, 3, 8), List(2, 6, 7), List(4, 5))
List(List(1, 6, 7), List(2, 3, 8), List(4, 5))
List(List(1, 6, 8), List(2, 3, 7), List(4, 5))
List(List(1, 7, 8), List(2, 3, 6), List(4, 5))
List(List(1, 2, 4), List(5, 6, 7), List(3, 8))
List(List(1, 2, 5), List(4, 6, 7), List(3, 8))
List(List(1, 2, 6), List(4, 5, 7), List(3, 8))
List(List(1, 2, 7), List(4, 5, 6), List(3, 8))
List(List(1, 4, 5), List(2, 6, 7), List(3, 8))
List(List(1, 4, 6), List(2, 5, 7), List(3, 8))
List(List(1, 4, 7), List(2, 5, 6), List(3, 8))
List(List(1, 5, 6), List(2, 4, 7), List(3, 8))
List(List(1, 5, 7), List(2, 4, 6), List(3, 8))
List(List(1, 6, 7), List(2, 4, 5), List(3, 8))
List(List(1, 2, 4), List(5, 6, 8), List(3, 7))
List(List(1, 2, 5), List(4, 6, 8), List(3, 7))
List(List(1, 2, 6), List(4, 5, 8), List(3, 7))
List(List(1, 2, 8), List(4, 5, 6), List(3, 7))
List(List(1, 4, 5), List(2, 6, 8), List(3, 7))
List(List(1, 4, 6), List(2, 5, 8), List(3, 7))
List(List(1, 4, 8), List(2, 5, 6), List(3, 7))
List(List(1, 5, 6), List(2, 4, 8), List(3, 7))
List(List(1, 5, 8), List(2, 4, 6), List(3, 7))
List(List(1, 6, 8), List(2, 4, 5), List(3, 7))
List(List(1, 2, 4), List(5, 7, 8), List(3, 6))
List(List(1, 2, 5), List(4, 7, 8), List(3, 6))
List(List(1, 2, 7), List(4, 5, 8), List(3, 6))
List(List(1, 2, 8), List(4, 5, 7), List(3, 6))
List(List(1, 4, 5), List(2, 7, 8), List(3, 6))
List(List(1, 4, 7), List(2, 5, 8), List(3, 6))
List(List(1, 4, 8), List(2, 5, 7), List(3, 6))
List(List(1, 5, 7), List(2, 4, 8), List(3, 6))
List(List(1, 5, 8), List(2, 4, 7), List(3, 6))
List(List(1, 7, 8), List(2, 4, 5), List(3, 6))
List(List(1, 2, 4), List(6, 7, 8), List(3, 5))
List(List(1, 2, 6), List(4, 7, 8), List(3, 5))
List(List(1, 2, 7), List(4, 6, 8), List(3, 5))
List(List(1, 2, 8), List(4, 6, 7), List(3, 5))
List(List(1, 4, 6), List(2, 7, 8), List(3, 5))
List(List(1, 4, 7), List(2, 6, 8), List(3, 5))
List(List(1, 4, 8), List(2, 6, 7), List(3, 5))
List(List(1, 6, 7), List(2, 4, 8), List(3, 5))
List(List(1, 6, 8), List(2, 4, 7), List(3, 5))
List(List(1, 7, 8), List(2, 4, 6), List(3, 5))
List(List(1, 2, 5), List(6, 7, 8), List(3, 4))
List(List(1, 2, 6), List(5, 7, 8), List(3, 4))
List(List(1, 2, 7), List(5, 6, 8), List(3, 4))
List(List(1, 2, 8), List(5, 6, 7), List(3, 4))
List(List(1, 5, 6), List(2, 7, 8), List(3, 4))
List(List(1, 5, 7), List(2, 6, 8), List(3, 4))
List(List(1, 5, 8), List(2, 6, 7), List(3, 4))
List(List(1, 6, 7), List(2, 5, 8), List(3, 4))
List(List(1, 6, 8), List(2, 5, 7), List(3, 4))
List(List(1, 7, 8), List(2, 5, 6), List(3, 4))
List(List(1, 3, 4), List(5, 6, 7), List(2, 8))
List(List(1, 3, 5), List(4, 6, 7), List(2, 8))
List(List(1, 3, 6), List(4, 5, 7), List(2, 8))
List(List(1, 3, 7), List(4, 5, 6), List(2, 8))
List(List(1, 4, 5), List(3, 6, 7), List(2, 8))
List(List(1, 4, 6), List(3, 5, 7), List(2, 8))
List(List(1, 4, 7), List(3, 5, 6), List(2, 8))
List(List(1, 5, 6), List(3, 4, 7), List(2, 8))
List(List(1, 5, 7), List(3, 4, 6), List(2, 8))
List(List(1, 6, 7), List(3, 4, 5), List(2, 8))
List(List(1, 3, 4), List(5, 6, 8), List(2, 7))
List(List(1, 3, 5), List(4, 6, 8), List(2, 7))
List(List(1, 3, 6), List(4, 5, 8), List(2, 7))
List(List(1, 3, 8), List(4, 5, 6), List(2, 7))
List(List(1, 4, 5), List(3, 6, 8), List(2, 7))
List(List(1, 4, 6), List(3, 5, 8), List(2, 7))
List(List(1, 4, 8), List(3, 5, 6), List(2, 7))
List(List(1, 5, 6), List(3, 4, 8), List(2, 7))
List(List(1, 5, 8), List(3, 4, 6), List(2, 7))
List(List(1, 6, 8), List(3, 4, 5), List(2, 7))
List(List(1, 3, 4), List(5, 7, 8), List(2, 6))
List(List(1, 3, 5), List(4, 7, 8), List(2, 6))
List(List(1, 3, 7), List(4, 5, 8), List(2, 6))
List(List(1, 3, 8), List(4, 5, 7), List(2, 6))
List(List(1, 4, 5), List(3, 7, 8), List(2, 6))
List(List(1, 4, 7), List(3, 5, 8), List(2, 6))
List(List(1, 4, 8), List(3, 5, 7), List(2, 6))
List(List(1, 5, 7), List(3, 4, 8), List(2, 6))
List(List(1, 5, 8), List(3, 4, 7), List(2, 6))
List(List(1, 7, 8), List(3, 4, 5), List(2, 6))
List(List(1, 3, 4), List(6, 7, 8), List(2, 5))
List(List(1, 3, 6), List(4, 7, 8), List(2, 5))
List(List(1, 3, 7), List(4, 6, 8), List(2, 5))
List(List(1, 3, 8), List(4, 6, 7), List(2, 5))
List(List(1, 4, 6), List(3, 7, 8), List(2, 5))
List(List(1, 4, 7), List(3, 6, 8), List(2, 5))
List(List(1, 4, 8), List(3, 6, 7), List(2, 5))
List(List(1, 6, 7), List(3, 4, 8), List(2, 5))
List(List(1, 6, 8), List(3, 4, 7), List(2, 5))
List(List(1, 7, 8), List(3, 4, 6), List(2, 5))
List(List(1, 3, 5), List(6, 7, 8), List(2, 4))
List(List(1, 3, 6), List(5, 7, 8), List(2, 4))
List(List(1, 3, 7), List(5, 6, 8), List(2, 4))
List(List(1, 3, 8), List(5, 6, 7), List(2, 4))
List(List(1, 5, 6), List(3, 7, 8), List(2, 4))
List(List(1, 5, 7), List(3, 6, 8), List(2, 4))
List(List(1, 5, 8), List(3, 6, 7), List(2, 4))
List(List(1, 6, 7), List(3, 5, 8), List(2, 4))
List(List(1, 6, 8), List(3, 5, 7), List(2, 4))
List(List(1, 7, 8), List(3, 5, 6), List(2, 4))
List(List(1, 4, 5), List(6, 7, 8), List(2, 3))
List(List(1, 4, 6), List(5, 7, 8), List(2, 3))
List(List(1, 4, 7), List(5, 6, 8), List(2, 3))
List(List(1, 4, 8), List(5, 6, 7), List(2, 3))
List(List(1, 5, 6), List(4, 7, 8), List(2, 3))
List(List(1, 5, 7), List(4, 6, 8), List(2, 3))
List(List(1, 5, 8), List(4, 6, 7), List(2, 3))
List(List(1, 6, 7), List(4, 5, 8), List(2, 3))
List(List(1, 6, 8), List(4, 5, 7), List(2, 3))
List(List(1, 7, 8), List(4, 5, 6), List(2, 3))
List(List(2, 3, 4), List(5, 6, 7), List(1, 8))
List(List(2, 3, 5), List(4, 6, 7), List(1, 8))
List(List(2, 3, 6), List(4, 5, 7), List(1, 8))
List(List(2, 3, 7), List(4, 5, 6), List(1, 8))
List(List(2, 4, 5), List(3, 6, 7), List(1, 8))
List(List(2, 4, 6), List(3, 5, 7), List(1, 8))
List(List(2, 4, 7), List(3, 5, 6), List(1, 8))
List(List(2, 5, 6), List(3, 4, 7), List(1, 8))
List(List(2, 5, 7), List(3, 4, 6), List(1, 8))
List(List(2, 6, 7), List(3, 4, 5), List(1, 8))
List(List(2, 3, 4), List(5, 6, 8), List(1, 7))
List(List(2, 3, 5), List(4, 6, 8), List(1, 7))
List(List(2, 3, 6), List(4, 5, 8), List(1, 7))
List(List(2, 3, 8), List(4, 5, 6), List(1, 7))
List(List(2, 4, 5), List(3, 6, 8), List(1, 7))
List(List(2, 4, 6), List(3, 5, 8), List(1, 7))
List(List(2, 4, 8), List(3, 5, 6), List(1, 7))
List(List(2, 5, 6), List(3, 4, 8), List(1, 7))
List(List(2, 5, 8), List(3, 4, 6), List(1, 7))
List(List(2, 6, 8), List(3, 4, 5), List(1, 7))
List(List(2, 3, 4), List(5, 7, 8), List(1, 6))
List(List(2, 3, 5), List(4, 7, 8), List(1, 6))
List(List(2, 3, 7), List(4, 5, 8), List(1, 6))
List(List(2, 3, 8), List(4, 5, 7), List(1, 6))
List(List(2, 4, 5), List(3, 7, 8), List(1, 6))
List(List(2, 4, 7), List(3, 5, 8), List(1, 6))
List(List(2, 4, 8), List(3, 5, 7), List(1, 6))
List(List(2, 5, 7), List(3, 4, 8), List(1, 6))
List(List(2, 5, 8), List(3, 4, 7), List(1, 6))
List(List(2, 7, 8), List(3, 4, 5), List(1, 6))
List(List(2, 3, 4), List(6, 7, 8), List(1, 5))
List(List(2, 3, 6), List(4, 7, 8), List(1, 5))
List(List(2, 3, 7), List(4, 6, 8), List(1, 5))
List(List(2, 3, 8), List(4, 6, 7), List(1, 5))
List(List(2, 4, 6), List(3, 7, 8), List(1, 5))
List(List(2, 4, 7), List(3, 6, 8), List(1, 5))
List(List(2, 4, 8), List(3, 6, 7), List(1, 5))
List(List(2, 6, 7), List(3, 4, 8), List(1, 5))
List(List(2, 6, 8), List(3, 4, 7), List(1, 5))
List(List(2, 7, 8), List(3, 4, 6), List(1, 5))
List(List(2, 3, 5), List(6, 7, 8), List(1, 4))
List(List(2, 3, 6), List(5, 7, 8), List(1, 4))
List(List(2, 3, 7), List(5, 6, 8), List(1, 4))
List(List(2, 3, 8), List(5, 6, 7), List(1, 4))
List(List(2, 5, 6), List(3, 7, 8), List(1, 4))
List(List(2, 5, 7), List(3, 6, 8), List(1, 4))
List(List(2, 5, 8), List(3, 6, 7), List(1, 4))
List(List(2, 6, 7), List(3, 5, 8), List(1, 4))
List(List(2, 6, 8), List(3, 5, 7), List(1, 4))
List(List(2, 7, 8), List(3, 5, 6), List(1, 4))
List(List(2, 4, 5), List(6, 7, 8), List(1, 3))
List(List(2, 4, 6), List(5, 7, 8), List(1, 3))
List(List(2, 4, 7), List(5, 6, 8), List(1, 3))
List(List(2, 4, 8), List(5, 6, 7), List(1, 3))
List(List(2, 5, 6), List(4, 7, 8), List(1, 3))
List(List(2, 5, 7), List(4, 6, 8), List(1, 3))
List(List(2, 5, 8), List(4, 6, 7), List(1, 3))
List(List(2, 6, 7), List(4, 5, 8), List(1, 3))
List(List(2, 6, 8), List(4, 5, 7), List(1, 3))
List(List(2, 7, 8), List(4, 5, 6), List(1, 3))
List(List(3, 4, 5), List(6, 7, 8), List(1, 2))
List(List(3, 4, 6), List(5, 7, 8), List(1, 2))
List(List(3, 4, 7), List(5, 6, 8), List(1, 2))
List(List(3, 4, 8), List(5, 6, 7), List(1, 2))
List(List(3, 5, 6), List(4, 7, 8), List(1, 2))
List(List(3, 5, 7), List(4, 6, 8), List(1, 2))
List(List(3, 5, 8), List(4, 6, 7), List(1, 2))
List(List(3, 6, 7), List(4, 5, 8), List(1, 2))
List(List(3, 6, 8), List(4, 5, 7), List(1, 2))
List(List(3, 7, 8), List(4, 5, 6), List(1, 2))
Надеюсь, на этот раз я решил правильную проблему?