The original problem as posed by Eric Lippert was to write a function to produce all the combinations of *k* elements from a collection of *n* elements. So far I’ve ported the code to product all the combinations of *k* `true`

booleans in a collection of *n* booleans where \(k <= n\).

We can use the work we’ve done so far to solve the original problem. See Lippert Part 3 to follow along with his post.

My complete solution is stored as a gist here.

First I’ll create a `zipWhere`

method like he did.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

extension SequenceOf {
func zipWhere<S: SequenceType where
S.Generator.Element == Bool>(bools: S) -> SequenceOf<T>
{
return SequenceOf { () -> GeneratorOf<T> in
var generator = Zip2(self, bools).generate()
return GeneratorOf<T> {
var next = generator.next()
while next != nil {
let (v, b) = next!
if b {
return v
} else {
next = generator.next()
}
}
return nil
}
}
}
}

On line 6 I use the `Zip2`

structure to create a sequence of tuples out the elements in self and the sequence of bools.

Then I return a new `SequenceOf`

that only returns the elements from self that are paired up in a tuple with a true value from the booleans.

Now we can write the final function. It relies on my custom `map`

function mentioned in last post. First we generate all the boolean combinations using the `combinations`

function from last time. Then we use the `map`

function to transform each boolean combination into a combination of the elements in `s`

.

1
2
3
4
5
6
7
8
9

func combinations<S: SequenceType>(s: S, k: UInt) ->
SequenceOf<SequenceOf<S.Generator.Element>>
{
let sArray = Array(s); let sseq =
SequenceOf(s)
return combinations(UInt(sArray.count), k).map { sseq.zipWhere($0) }
}

See all the code