I'm writing a function that would take a list of character occurrences (List[(Char, Int)]
) in a string, and produce all subsets of that occurrence list.
So, given
List(('a', 2), ('b', 2))
It will produce
List(
List(),
List(('a', 1)),
List(('a', 2)),
List(('b', 1)),
List(('a', 1), ('b', 1)),
List(('a', 2), ('b', 1)),
List(('b', 2)),
List(('a', 1), ('b', 2)),
List(('a', 2), ('b', 2))
)
I've implemented it like this:
type Occurrences = List[(Char, Int)]
def combinations(occurrences: Occurrences): List[Occurrences] =
if (occurrences.isEmpty) List(List())
else for {
(c, n) <- occurrences
i <- n to 1 by -1
} yield (c, i) :: combinations(occurrences.tail)
And I get this error:
type mismatch;
found : List[List[Product with Serializable]]
required: List[Occurrences]
(which expands to) List[List[(Char, Int)]]
Please help me understand, why is this happening, and how do I fix it?
I've tried re-writing it as a flatMap..., using Intellij's "Explain Scala code" etc.
Actually brackets are missing:
type Occurrences = List[(Char, Int)]
def combinations(occurrences: Occurrences): List[Occurrences] =
if (occurrences.isEmpty) List(List())
else (for {
(c, n) <- occurrences
i <- n to 1 by -1
} yield (c, i)) :: combinations(occurrences.tail)
In you original code for comprehension tried to yield (c, i) :: combinations(occurrences.tail)
which is List
with Any
element inside (Tuple
/another List
).
UPDATE:
The proper method that does required magic:
type Occurrences = List[(Char, Int)]
/**
* Returns the list of all subsets of the occurrence list.
* This includes the occurrence itself, i.e. `List(('k', 1), ('o', 1))`
* is a subset of `List(('k', 1), ('o', 1))`.
* It also include the empty subset `List()`.
*
* Example: the subsets of the occurrence list `List(('a', 2), ('b', 2))` are:
*
* List(
* List(),
* List(('a', 1)),
* List(('a', 2)),
* List(('b', 1)),
* List(('a', 1), ('b', 1)),
* List(('a', 2), ('b', 1)),
* List(('b', 2)),
* List(('a', 1), ('b', 2)),
* List(('a', 2), ('b', 2))
* )
*
* Note that the order of the occurrence list subsets does not matter -- the subsets
* in the example above could have been displayed in some other order.
*/
def combinations(occurrences: Occurrences): List[Occurrences] =
occurrences.foldRight(List[Occurrences](Nil)) {
case ((ltr, cnt), acc) =>
acc ::: (for {
comb <- acc
ltrNum <- 1 to cnt
} yield (ltr, ltrNum) :: comb)
}
All kudos to the author of this code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With