Skip to content

Instantly share code, notes, and snippets.

@JadenGeller
Last active December 17, 2023 00:43
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 JadenGeller/5f028c184cda42d16f41ad0da4908649 to your computer and use it in GitHub Desktop.
Save JadenGeller/5f028c184cda42d16f41ad0da4908649 to your computer and use it in GitHub Desktop.
Union-Find disjoint-set data structure in Swift
public protocol UnificationSystemProtocol {
associatedtype Variable
mutating func makeFreshVariable() -> Variable
mutating func canonicalVariable(for variable: Variable) -> Variable
@discardableResult
mutating func unify(_ first: Variable, _ second: Variable) -> Bool
}
public struct UnificationSystem: UnificationSystemProtocol {
public typealias Variable = Int
private var parent: [Variable] = []
private var rank: [Int] = []
public init() {}
public mutating func makeFreshVariable() -> Variable {
let variable = parent.count
parent.append(variable)
rank.append(0)
return variable
}
public mutating func canonicalVariable(for variable: Variable) -> Variable {
guard parent[variable] != variable else { return variable }
parent[variable] = canonicalVariable(for: parent[variable])
return parent[variable]
}
@discardableResult
public mutating func unify(_ lhs: Variable, _ rhs: Variable) -> Bool {
let lhs = canonicalVariable(for: lhs)
let rhs = canonicalVariable(for: rhs)
guard lhs != rhs else { return false }
if rank[lhs] < rank[rhs] {
parent[lhs] = rhs
} else if rank[lhs] > rank[rhs] {
parent[rhs] = lhs
} else {
parent[rhs] = lhs
rank[lhs] += 1
}
return true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment