CW Holeman II
CW Holeman II

Reputation: 4961

Get subsets of a range of sizes in Scala?

I can get subsets of a specific size or all of them.

scala> println((1 to 25).toSet.subsets.size)
33554432
scala> println((1 to 25).toSet.subsets(1).size)
25
scala> println((1 to 25).toSet.subsets(10).size)
1

To get just the subsets of size, say 10 or less, I could fall back to a loop and take the union. What would be a functional programming way of doing this?

Upvotes: 2

Views: 156

Answers (2)

Leo C
Leo C

Reputation: 22449

You can use flatMap as follows:

(1 to 10).flatMap((1 to 25).toSet.subsets(_))

For example, below is a list of all subsets of size up to 3 in a Set of 6 elements:

(1 to 3).flatMap((1 to 6).toSet.subsets(_))
// res1: scala.collection.immutable.IndexedSeq[scala.collection.immutable.Set[Int]] = Vector(
//   Set(5), Set(1), Set(6), Set(2), Set(3), Set(4),
//   Set(5, 1), Set(5, 6), Set(5, 2), Set(5, 3), Set(5, 4), Set(1, 6),
//   Set(1, 2), Set(1, 3), Set(1, 4), Set(6, 2), Set(6, 3), Set(6, 4),
//   Set(2, 3), Set(2, 4), Set(3, 4),
//   Set(5, 1, 6), Set(5, 1, 2), Set(5, 1, 3), Set(5, 1, 4), Set(5, 6, 2),
//   Set(5, 6, 3), Set(5, 6, 4), Set(5, 2, 3), Set(5, 2, 4), Set(5, 3, 4),
//   Set(1, 6, 2), Set(1, 6, 3), Set(1, 6, 4), Set(1, 2, 3), Set(1, 2, 4),
//   Set(1, 3, 4), Set(6, 2, 3), Set(6, 2, 4), Set(6, 3, 4), Set(2, 3, 4)
// )

Upvotes: 3

jwvh
jwvh

Reputation: 51271

I think this is what you're after. (Using smaller numbers for visual verification.)

(2 to 4).flatMap(Set(1 to 5:_*).subsets)
//res0 = Vector(Set(5, 1), Set(5, 2), Set(5, 3), Set(5, 4), Set(1, 2), Set(1, 3), Set(1, 4), Set(2, 3), Set(2, 4), Set(3, 4), Set(5, 1, 2), Set(5, 1, 3), Set(5, 1, 4), Set(5, 2, 3), Set(5, 2, 4), Set(5, 3, 4), Set(1, 2, 3), Set(1, 2, 4), Set(1, 3, 4), Set(2, 3, 4), Set(5, 1, 2, 3), Set(5, 1, 2, 4), Set(5, 1, 3, 4), Set(5, 2, 3, 4), Set(1, 2, 3, 4))

Upvotes: 1

Related Questions