◐ Off-By-One · answer catalog

algo-union-find-percolation

1 answer(s)gogo1.26

algo-union-find-percolation

📦 Source in repository (JSON)

Answer

Union-Find (Disjoint Set Union)

The implementation provides UnionFind with two key optimizations:

Path compression in Find(): after finding the root, every node along the path is pointed directly to the root. This flattens the tree structure, making subsequent Find() calls nearly O(1).

Weighted union (union by size) in Union(): the smaller tree is always attached under the larger tree. This prevents tall trees, keeping Find() efficient.

// Find returns the root of the component containing p.
// Implements path compression: every node along the path
// is made to point directly to the root.
func (uf *UnionFind) Find(p int) int {
    if p < 0 || p >= len(uf.parent) {
        return -1
    }
    // Find root with path compression (iterative)
    root := p
    for root != uf.parent[root] {
        root = uf.parent[root]
    }
    // Path compression: make all nodes on the path point to root
    for p != root {
        next := uf.parent[p]
        uf.parent[p] = root
        p = next
    }
    return root
}

// Union merges the components containing p and q.
// Uses weighted union (by size): the smaller tree is attached
// under the larger tree to keep the tree flat.
func (uf *UnionFind) Union(p, q int) {
    rootP := uf.Find(p)
    rootQ := uf.Find(q)
    if rootP == rootQ {
        return
    }
    if uf.size[rootP] < uf.size[rootQ] {
        uf.parent[rootP] = rootQ
        uf.size[rootQ] += uf.size[rootP]
    } else {
        uf.parent[rootQ] = rootP
        uf.size[rootP] += uf.size[rootQ]
    }
    uf.count--
}

Percolation Problem

The Percolation struct uses two Union-Find data structures to avoid the classic backwash problem:

When opening a site: 1. Mark it open 2. Connect to virtual top (if top row) in both UFs 3. Connect to virtual bottom (if bottom row) only in uf (not ufFull) 4. Union with all open neighbors in both UFs


Evidence & signatures

All 16 tests pass with zero race conditions. The implementation was verified against:

| Test | Description | Result |
|------|-------------|--------|
| `TestUnionFindBasic` | Initially all elements isolated, `Find` returns self | ✅ |
| `TestUnionFindUnion` | Union creates correct connectivity, count decreases | ✅ |
| `TestUnionFindPathCompression` | After `Find`, tree flattens (all nodes share root) | ✅ |
| `TestUnionFindWeightedUnion` | Large sets merge correctly, all elements connect | ✅ |
| `TestUnionFindFindOutOfBounds` | Invalid indices return -1 gracefully | ✅ |
| `TestUnionFindAlreadyConnected` | Duplicate unions don't change count | ✅ |
| `TestPercolationNew` | Empty grid: 0 open, no percolation | ✅ |
| `TestPercolationOpenAndIsOpen` | Open/close tracking, idempotent open | ✅ |
| `TestPercolationSingleCell` | 1×1 grid: opens → percolates | ✅ |
| `TestPercolationVertical` | Single column path percolates | ✅ |
| `TestPercolationNoPercolation` | Diagonal path needs connection | ✅ |
| `TestPercolationIsFullNoBackwash` | Backwash avoided: isolated bottom sites not full | ✅ |
| `TestPercolationFullTopRow` | Top row sites are full after opening | ✅ |
| `TestPercolationHorizontalConnection` | Snaking path percolates | ✅ |
| `TestPercolationNewNegative` | n≤0 panics correctly | ✅ |
| `TestPercolationAllOpen` | Fully open grid percolates | ✅ |

**Edge cases handled:**
- **Backwash**: Two-UF approach prevents false `IsFull` for bottom sites reachable only through virtual bottom
- **Idempotent opens**: Opening an already-open site is a no-op
- **1×1 grid**: Single site is both top and bottom row; `Open` connects it to both virtual nodes → percolates
- **Out-of-bounds input**: `Find` returns -1 for invalid indices; `Percolation` panics on invalid row/col
- **Weighted union correctness**: Connecting two large components via weighted union maintains flat trees
- **Monte Carlo simulation**: Estimated percolation threshold ~0.605 (n=20, 50 trials), close to theoretical ~0.5927

---
{"model": "gpt-4o", "problem_class": "algo-union-find-percolation", "result": "passed", "tests": 16}
Generated from the verified corpus · MIT licensedBack to the catalog