Code Katas
Implementation drills. Pick any language. For each kata, write the data structure from scratch, add a minimal test harness, and record a two-to-three line note on what the bug-per-attempt pattern taught you.
Kata 1 - Red-Black Tree Insertion
Implement:
insert(key)with fix-up loop that handles the three canonical uncle cases (red uncle, black uncle with left-right or right-left zig-zag, black uncle with straight line)- left and right rotation primitives
- a post-insert validator that checks the five red-black invariants
Target: O(log n) insert, all five invariants hold after every call, passes a 10,000-insert randomized test with invariant check after each call.
Bonus: add delete(key) with the four deletion fix-up cases.
Kata 2 - Union-Find with Rank and Path Compression
Implement:
make_set(x)find(x)with path compression (either full compression or path halving)union(x, y)with union by rank
Target: a sequence of n = 200,000 make_set calls followed by 200,000 random union/find operations should complete in under 100 ms on a modern laptop. Verify correctness by cross-checking against a brute-force equivalence-class implementation on small inputs.
Bonus: instrument and plot amortized cost per operation; confirm it stays roughly constant as n grows.
Kata 3 - Segment Tree with Lazy Propagation
Implement:
- build from an array of length
n - point update
update(i, v) - range query
query(l, r)for sum (or min, or max - pick one) - range update
update(l, r, delta)using alazy[node]array
Target: correctness against a brute-force array on 1,000 randomized mixed operation sequences, each with n = 200. Then scale to n = 10^5 and run 10^5 mixed operations in under 500 ms.
Bonus: support a second combine operation (e.g., both range-sum and range-min in the same tree).
Kata 4 - Fenwick Tree (Binary Indexed Tree)
Implement:
update(i, delta)for point updatequery(i)for prefix sumarr[1..i]query(l, r) = query(r) - query(l-1)for range sum
Target: both operations use only the low-bit trick i & (-i). Correctness checked against brute-force prefix sums on randomized inputs. Handle n = 10^6 with 10^6 mixed updates and queries in under 300 ms.
Bonus: extend to 2-D Fenwick tree for rectangular range sum on a grid.
Kata 5 - Skip List
Implement:
- randomized
insert(key)that tosses coins to determine the node's level search(key)delete(key)- a configurable
MAX_LEVELandp(typically0.5or0.25)
Target: correctness on 10,000 randomized operations compared against a sorted reference set. Measured expected per-operation time should stay O(log n) as n scales from 10^3 to 10^6.
Bonus: report the achieved level distribution and compare against the geometric expectation.
Kata 6 - Bloom Filter
Implement:
init(m, k)with a bit array of lengthmandkhash functions (use double-hashingh_i(x) = h1(x) + i * h2(x))insert(x)contains(x)returningtrueif allkbits are set,falseotherwise
Target: empirical false-positive rate should match the theoretical prediction (1 - e^(-kn/m))^k to within 10% on a test workload of n = 10,000 inserts, followed by 100,000 membership queries for values not in the set.
Bonus: compare measured memory against a Python set containing the same keys; report the compression factor.
Completion Checklist
- all six katas compile, pass randomized tests, and hit the stated time targets
- each kata has a one-paragraph reflection on the main bug encountered during implementation
- at least one instrumented run of kata 2 plotted to confirm near-constant amortized cost
- at least one instrumented run of kata 6 compared to the theoretical false-positive formula
Core Structure Repair Katas
Complete these if any advanced structure feels like magic.
- Implement a singly linked list with
push_front,append,find,delete_first, andreverse. - Implement a stack with array storage and use it to check balanced delimiters.
- Implement a queue with a circular buffer and prove each operation is
O(1)amortized or worst-case. - Implement binary-tree traversals: preorder, inorder, postorder, and level order.
- Implement a binary min-heap and use it for top-K selection.
- Implement a hash table with chaining and a resize threshold.
Evidence check: every kata must include unit tests, one edge-case test, and a complexity note for each public operation.