Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package disjointset is union-find (a disjoint-set forest) as a pure, reusable package: it tracks a partition of \[0, ...

Readme View source

gno.land/p/moul/x/daily/disjointset/v0

Union-find (disjoint-set forest)New, Find, Union, Connected, Size, Groups, Partition, MaxN.

Tracks a partition of [0, n) into disjoint groups and answers "same group?" in near-constant time.

1import "gno.land/p/moul/x/daily/disjointset/v0"
2
3d := disjointset.New(10)
4d.Union(0, 1)
5d.Union(1, 3)
6d.Connected(0, 3)   // true
7d.Groups()          // 8
8d.Partition()       // [[0 1 3] [2] [4] ...]

Both optimisations, because they only work together: path compression flattens the tree on every Find, union by rank keeps the shallower tree under the deeper one. With both, operations are O(α(n)) — inverse Ackermann, effectively constant. With neither, a chain of unions degrades to O(n) per query, which on chain is the difference between a cheap call and running out of gas. Find compresses iteratively: a deep chain would otherwise risk the call stack.

Partition returns groups sorted ascending and ordered by their smallest member, so the result is identical regardless of the order unions were applied — that determinism is what makes it safe to put in a Render.

Out-of-range indices return -1/false/0 rather than panicking, and are connected to nothing — not even to themselves.

Live demo: r/moul/x/daily/disjointsetdemo · render it at /r/moul/x/daily/disjointsetdemo/v0.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.

Overview

Package disjointset is union-find (a disjoint-set forest) as a pure, reusable package: it tracks a partition of [0, n) into disjoint groups and answers "are these two in the same group?" in near-constant time.

Both classic optimisations are implemented, and they matter together: path compression flattens a tree on every Find, union by rank keeps the shallower tree under the deeper one. With both, operations are O(α(n)) — inverse Ackermann, effectively constant. With neither, a chain of unions degrades to O(n) per query, which on chain is the difference between a cheap call and an out-of-gas one.

A live demo of this package is at r/moul/x/daily/disjointsetdemo(/r/moul/x/daily/disjointsetdemo/v0).

Constants 1

const MaxN

1const MaxN = 1 << 16
source

MaxN bounds a set so allocation stays predictable.

Functions 1

func New

1func New(n int) *DisjointSet
source

New returns n singleton groups. n is clamped to [0, MaxN].

Types 1

type DisjointSet

struct
1type DisjointSet struct {
2	parent []int
3	rank   []int
4	groups int
5}
source

DisjointSet is a partition of [0, n) into disjoint groups.

Methods on DisjointSet

func Connected

method on DisjointSet
1func (d *DisjointSet) Connected(a, b int) bool
source

Connected reports whether a and b are in the same group. Out-of-range indices are not connected to anything, including themselves.

func Find

method on DisjointSet
1func (d *DisjointSet) Find(i int) int
source

Find returns the representative of i's group, or -1 when i is out of range.

Path compression: every node visited is re-pointed straight at the root, so the next Find on any of them is O(1). Done iteratively rather than recursively — a deep chain would otherwise risk the call stack.

func Groups

method on DisjointSet
1func (d *DisjointSet) Groups() int
source

Groups returns how many disjoint groups remain.

func InRange

method on DisjointSet
1func (d *DisjointSet) InRange(i int) bool
source

InRange reports whether i is a valid element.

func Len

method on DisjointSet
1func (d *DisjointSet) Len() int
source

Len returns the number of elements.

func Partition

method on DisjointSet
1func (d *DisjointSet) Partition() [][]int
source

Partition returns the groups, each sorted ascending, ordered by their smallest member — deterministic regardless of the union order, which is what makes it safe to render.

func Size

method on DisjointSet
1func (d *DisjointSet) Size(i int) int
source

Size returns how many elements share i's group, or 0 when out of range.

func Union

method on DisjointSet
1func (d *DisjointSet) Union(a, b int) bool
source

Union merges the groups of a and b and reports whether they were merged. False means they were already together, or an index was out of range.

Source Files 3