Skip to content

Instantly share code, notes, and snippets.

@oisdk
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oisdk/f048c39dbe4d15106b1f to your computer and use it in GitHub Desktop.
Save oisdk/f048c39dbe4d15106b1f to your computer and use it in GitHub Desktop.
struct ProdGen<C : CollectionType> : GeneratorType {
typealias Element = [C.Generator.Element]
private let seqs: [C]
private var gens: [C.Generator]
private var cur: Element
mutating func next() -> Element? {
for i in gens.indices.reverse() {
if let n = gens[i].next() {
cur[i] = n
return cur
} else {
gens[i] = seqs[i].generate()
cur[i] = gens[i].next()!
}
}
return nil
}
// mutating func next() -> Element? {
// if let n = gens[i].next() {
// cur[i] = n
// i = gens.count - 1
// return cur
// }
// gens[i] = seqs[i].generate()
// cur[i] = gens[i].next()!
// return --i < 0 ? nil : next()
// }
init(seqs: [C]) {
var gens = seqs.map{$0.generate()}
self.seqs = seqs
self.cur = dropLast(gens).indices.map{gens[$0].next()!} + [self.seqs.last!.first!]
self.gens = gens
}
}
struct ProdSeq<C : CollectionType> : SequenceType {
typealias Generator = ProdGen<C>
private let seqs: [C]
func generate() -> Generator {
return ProdGen( seqs: seqs )
}
}
func product<C : CollectionType>(cols: [C]) -> ProdSeq<C> {
return ProdSeq(seqs: cols)
}
extension SequenceType where Generator.Element : SequenceType {
func product() -> ProdSeq<[Generator.Element.Generator.Element]> {
return ProdSeq(seqs: self.map{Array($0)})
}
}
extension SequenceType where Generator.Element : CollectionType {
func product() -> ProdSeq<Generator.Element> {
return ProdSeq(seqs: Array(self))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment