Skip to content

Instantly share code, notes, and snippets.

@timvermeulen
Last active March 24, 2020 18:30
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 timvermeulen/3448e411c7c2947fbf01bb062e565704 to your computer and use it in GitHub Desktop.
Save timvermeulen/3448e411c7c2947fbf01bb062e565704 to your computer and use it in GitHub Desktop.
func product<A: Collection, B: Collection>(_ a: A, _ b: B) -> CartesianProductCollection<A, B> {
return CartesianProductCollection(a, b)
}
struct CartesianProductCollection<A: Collection, B: Collection> {
let a: A
let b: B
init(_ a: A, _ b: B) {
self.a = a
self.b = b
}
}
extension CartesianProductCollection: Collection {
typealias Index = CartesianProductIndex<A.Index, B.Index>
typealias Element = (A.Iterator.Element, B.Iterator.Element)
var startIndex: Index { return Index(a.startIndex, b.startIndex) }
var endIndex: Index { return Index(a.endIndex, b.startIndex) }
func index(after index: Index) -> Index {
let next = b.index(after: index.b)
if next == b.endIndex { return Index(a.index(after: index.a), b.startIndex) }
else { return Index(index.a, next) }
}
subscript(index: Index) -> Element {
return (a[index.a], b[index.b])
}
}
struct CartesianProductIndex<A: Comparable, B: Comparable> {
let a: A
let b: B
var pair: (A, B) { return (a, b) }
init(_ a: A, _ b: B) {
self.a = a
self.b = b
}
}
extension CartesianProductIndex: Comparable {
static func == (left: CartesianProductIndex, right: CartesianProductIndex) -> Bool {
return left.pair == right.pair
}
static func < (left: CartesianProductIndex, right: CartesianProductIndex) -> Bool {
return left.pair < right.pair
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment