Skip to content

Instantly share code, notes, and snippets.

@seadiem
Last active September 30, 2019 13:12
Show Gist options
  • Save seadiem/657e3f946400d8c1e965ba220d0fc21f to your computer and use it in GitHub Desktop.
Save seadiem/657e3f946400d8c1e965ba220d0fc21f to your computer and use it in GitHub Desktop.
Each To Each (Generic)
/// [1, 2, 3, 4, 5, 6] -> (1,2) (1,3) (1,3) (1,4) (1,5) (1, 6) (2,3) (2,4) (2,5) (2,6) ...
public func eachToEachIn<C: Collection>(c: C) -> [(left: C.Element, right: C.Element)]? where C.Element: Hashable {
guard c.count > 1 else { return nil }
var rightindex = c.startIndex
var leftindex = c.startIndex
var controlSet = Set<CoupleUnorderer<C.Element>>()
while rightindex < c.endIndex {
while leftindex < c.endIndex {
let left = c[leftindex]
let right = c[rightindex]
if left != right {
let tuple = CoupleUnorderer(left: left, right: right)
controlSet.insert(tuple)
}
leftindex = c.index(after: leftindex)
if leftindex == c.endIndex { break }
}
leftindex = c.startIndex
rightindex = c.index(after: rightindex)
if rightindex == c.endIndex { break }
}
return controlSet.map { $0.tuple }
}
public struct CoupleUnorderer<Element>: Equatable, Hashable where Element: Hashable {
public let left: Element
public let right: Element
public init(left: Element, right: Element) {
self.left = left
self.right = right
}
var tuple: (left: Element, right: Element) { (left, right) }
public static func == (lhs: CoupleUnorderer<Element>, rhs: CoupleUnorderer<Element>) -> Bool {
let leftset: Set = [lhs.left, lhs.right]
let rightset: Set = [rhs.left, rhs.right]
return leftset == rightset
}
public func hash(into hasher: inout Hasher) {
let set: Set = [left, right]
hasher.combine(set)
}
}
// Testing
struct RefineCollections {
func testEachToEach() {
let array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
if let result = eachToEachIn(c: array) {
sortresult(result: result)
}
}
func testEmpty() {
let array = [Int]()
if let result = eachToEachIn(c: array) {
sortresult(result: result)
}
}
func testOne() {
let array = [1]
if let result = eachToEachIn(c: array) {
sortresult(result: result)
}
}
func testTwo() {
let array = [3, 1]
if let result = eachToEachIn(c: array) {
sortresult(result: result)
}
}
func testThree() {
let array = [1, 2, 3]
if let result = eachToEachIn(c: array) {
sortresult(result: result)
}
}
func sortresult(result: [(left: Int, right: Int)]) {
var result = result
result.sort { $0.left < $1.left }
result.sort { $0.right < $1.right }
result.forEach { print($0) }
}
func testSet() {
let one: Set = [2, 1]
let two: Set = [1, 2]
print(one == two)
}
func test() {
print("test empty")
testEmpty()
print("test one")
testOne()
print("test two")
testTwo()
print("test three")
testThree()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment