All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.weso.utils.SetUtils.scala Maven / Gradle / Ivy

The newest version!
package es.weso.utils
// import scala.collection.compat._
import es.weso.utils.internal.CollectionCompat._

object SetUtils {

  /** paritition of a set in n sets whose union give that set again Example: partition(Set(1,2),2) = Stream( List(Set(1,
    * 2), Set[Int]()), List(Set(2), Set(1)), List(Set(1), Set(2)), List(Set[Int](), Set(1, 2)) )
    *
    * partition(Set(1,2),3) = Stream( List(Set(1, 2), Set[Int](), Set[Int]()), List(Set(2), Set(1), Set[Int]()),
    * List(Set(2), Set[Int](), Set(1)), List(Set(1), Set(2), Set[Int]()), List(Set(1), Set[Int](), Set(2)),
    * List(Set[Int](), Set(1, 2), Set[Int]()), List(Set[Int](), Set(2), Set(1)), List(Set[Int](), Set(1), Set(2)),
    * List(Set[Int](), Set[Int](), Set(1, 2)) )
    *
    * @param set
    *   set of elements
    * @param n
    *   number of sets to generate
    * @tparam A
    *   type of values
    * @return
    *   a list of sets
    */
  def partition[A](set: Set[A], n: Int): LazyList[List[Set[A]]] = n match {
    case 1 => LazyList(List(set))
    case n if n > 1 =>
      for {
        pair <- pSet(set)
        (s1, s2) = pair
        rest <- partition(s2, n - 1)
      } yield List(s1) ++ rest
    case _ => throw new Exception(s"partition invoked with wrong n: $n")
  }

  /** Tail recursive pSet pSet s generates the power set of s, pairing each subset with its complement. Example:
    * pSet(Set(1,2)) = Stream((Set(1,2),Set()),(Set(1),Set(2)),(Set(2),Set(1)),(Set(),Set(1,2))).
    */
  def pSet[A](set: Set[A]): LazyList[(Set[A], Set[A])] = {

    @annotation.tailrec
    def pSetRec(set: Set[A], acc: LazyList[(Set[A], Set[A])]): LazyList[(Set[A], Set[A])] = {
      if (set.isEmpty) acc
      else {
        val x = set.head
        pSetRec(set.tail, acc.map(addFirst(x)) ++ acc.map(addSecond(x)))
      }
    }
    pSetRec(set, LazyList((Set(), Set())))
  }

  private def addFirst[A](x: A)(pair: (Set[A], Set[A])): (Set[A], Set[A]) = {
    (pair._1 + x, pair._2)
  }

  private def addSecond[A](x: A)(pair: (Set[A], Set[A])): (Set[A], Set[A]) = {
    (pair._1, pair._2 + x)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy