This repository is a learning library for algorithms. Each package explains one topic in clear, beginner-friendly language and shows why it works using loop invariants.
The repository is organized as a MoonBit workspace. The root module keeps the
introductory examples and command-line sandbox, while algorithm packages live in
domain modules under modules/.
If you are new to algorithms, you can read these packages like a book. Each README is designed to be understandable without heavy math.
modules/graph: graph, tree, shortest path, flow, matching, and connectivity algorithmsmodules/data_structures: Fenwick trees, segment trees, sparse tables, treaps, tries, and related structuresmodules/string: string matching, hashing, suffix structures, and automatamodules/math: number theory, algebra, transforms, recurrence, and linear algebra routinesmodules/geometry: computational geometry algorithmsmodules/dp: dynamic programming examples and optimizationsmodules/techniques: general competitive-programming techniques and search/window patternsmodules/persistent: persistent data structure examplesmodules/verified: small verified examples with proof-oriented loop invariants
- How to translate a problem into a step-by-step algorithm
- How to reason about correctness with loop invariants
- How to write clean, testable MoonBit implementations
Each package README follows this structure:
- Problem statement in simple terms
- Core idea (the intuition)
- Step-by-step algorithm
- Multiple examples
- Complexity and pitfalls
Think of the README as a Wikipedia article: definition, motivation, examples, then implementation notes.
README.mbt.md files include code blocks tagged mbt check. These blocks are
compiled and run by moon test, so documentation stays correct.
If you want a snippet that should not run, use mbt nocheck instead.
///|
test "doc example runs" {
inspect(1 + 1, content="2")
}A loop invariant is a sentence that stays true every time the loop repeats. It connects code to reasoning.
A good invariant explains:
- what has been computed so far
- what remains to be processed
- why the algorithm will be correct at the end
We want the sum of all elements. The invariant is:
"After processing the first i elements, sum equals their total."
///|
test "invariant sum example" {
let xs : Array[Int] = [1, 2, 3, 4]
let n = xs.length()
let total = for i = 0, sum = 0; i < n; {
continue i + 1, sum + xs[i]
} nobreak {
sum
} where {
proof_invariant: 0 <= i && i <= n,
proof_reasoning: "sum equals the total of xs[0..i).",
}
inspect(total, content="10")
}We keep a running maximum. The invariant is:
"best is the maximum of elements seen so far."
///|
test "invariant max example" {
let xs : Array[Int] = [2, 7, 1, 5]
let n = xs.length()
let best = for i = 0, best = xs[0]; i < n; {
let v = xs[i]
continue i + 1, if v > best { v } else { best }
} nobreak {
best
} where {
proof_invariant: 0 <= i && i <= n,
proof_reasoning: "best is max of xs[0..i).",
}
inspect(best, content="7")
}For very simple loops, a for .. in loop is clearer and needs no invariant.
///|
test "simple loop example" {
let xs : Array[Int] = [1, 2, 3]
let sum = for v in xs; sum = 0 {
continue sum + v
} nobreak {
sum
}
inspect(sum, content="6")
}Each algorithm package lives in modules/<domain>/<name>/ and has:
README.mbt.md(the tutorial).mbtsource files (the implementation)- tests (often inside the README itself)
Each domain module also has a README.md that explains the package family.
If a README feels too advanced, pick an easier package first and return later.
Start small and build up:
- Basics:
modules/data_structures/union_find,modules/data_structures/fenwick,modules/data_structures/segment_tree - Dynamic Programming:
modules/dp/dp,modules/math/linear_recurrence - Strings:
modules/string/kmp,modules/string/aho_corasick,modules/string/suffix_array - Graphs:
modules/graph/dijkstra,modules/graph/bellman_ford,modules/graph/mst - Advanced:
modules/graph/centroid,modules/data_structures/linkcut,modules/data_structures/segment_tree_beats
Run these from the workspace root:
moon check
moon test
moon info
moon fmt
moon run cmd/mainWhen improving a tutorial:
- Keep it beginner-friendly
- Add multiple examples
- Explain why the algorithm works
- Mention complexity and pitfalls
See LICENSE.