0

I would like to determine all partitions of a given list of integers {1,...,n}, where the elements of the partitions possess a specific cardinality k in {1,Nmin,...,Nmax}.

For example: given a list of integers {1,2,3,4} all partitions should be determined, for which the elements of the partitions posses a cardinality in {1,Nmin=2,...,Nmax=3}, i.e. P1 = {{1,2},{3,4}}, P2={{1,3},{2,4}}, P3={{2,3},{1,4}},P4={{1},{2,3,4}},P5={{2},{1,3,4}}, P6={{3},{1,2,3}}, P7={{4},{1,2,3}}, P8={{1,2},{3},{4}}, P9={{2,3},{1},{4}}, P10={{3,4},{1},{2}}, P11={{1,4},{2},{3}}.

The function should look like:

def detPartSpecSubSize(n: Int,Nmin: Int,Nmax:int) : List[List[List[Int]]] {
... 
}

In the example above n = 4, Nmin=2 and Nmax = 3 and the output P={P1,P2,...,P11}.

I would like to do it in Scala in a recursive manner...

user1537137
  • 121
  • 5
  • 1
    All the questions where you show your effort in answering them by yourself are more than welcome. That's how you and the community benefit. Posting only the question makes it look like someone's too lazy to even make a code stub. – Haris Osmanagić Mar 25 '14 at 12:38

1 Answers1

0
  def detPartSpecSubSize(n: Int, Nmin: Int, Nmax: Int): List[List[List[Int]]] = {
    val all = (1 to n).toList
    val cardinalityList = (Nmin to Nmax).toSet + 1

    def _detPartSpecSubSize(elements: Set[Int]): Set[Set[List[Int]]] = {
      def subsets(card: Int): List[List[Int]] = {
        def _subsets(elements_ : Set[Int], n: Int): Set[Set[Int]] = {
          if (n == 0 || elements_.size < n) Set(Set())
          else {
            for {
              elem <- elements_
              moreElem <- _subsets(elements_ - elem, n - 1)
              if (1 + moreElem.size == n)
            } yield (moreElem + elem)
          }

        }

        _subsets(elements, card).toList.map(_.toList)
      }

      if (elements.size == 0) Set(Set())
      else {
        for {
          c <- cardinalityList
          part <- subsets(c)
          if (part.length == c)
          rest = elements -- part.toSet
          more <- _detPartSpecSubSize(rest.toSet)

        } yield more + part
      }
    }

    _detPartSpecSubSize(all.toSet).toList.map(_.toList)
  } 

The output from detPartSpecSubSize(4, 2, 3) is:

List(List(4), List(3, 2, 1))
List(List(2), List(4, 3, 1))
List(List(4), List(3), List(2, 1))
List(List(3), List(1), List(4, 2))
List(List(3), List(2), List(4, 1))
List(List(4), List(1), List(3, 2))
List(List(1), List(4, 3, 2))
List(List(4), List(3), List(2), List(1))
List(List(4, 3), List(2, 1))
List(List(4, 1), List(3, 2))
List(List(4, 2), List(3, 1))
List(List(2), List(1), List(4, 3))
List(List(3), List(4, 2, 1))
List(List(4), List(2), List(3, 1))
atretkow
  • 362
  • 2
  • 8