Assign levels (seeded)
# grade this stage (from your course directory)
npx theinference test --stage assign-levels --watchTurn the formula into code. Draw one level per element, in the fixed insertion order 0..n-1, using the seeded mulberry32(seed) PRNG. This array is the skeleton of the entire tower.
Same seed + same call order ⇒ the same level array on every machine. This is what makes the whole course deterministic: the graph is a pure function of (vectors, seed, params). Call the PRNG exactly once per element, in id order — no extra draws, no reordering.
What to build
Implement runAssignLevels
Implement assignLevel(rng, mL) and assignAllLevels(seed, n, M) in src/levels.ts, then expose runAssignLevels(seed, n, M) returning the level array (one integer per element).
export function runAssignLevels(seed: number, n: number, M: number): number[] {
// mL = 1/ln(M); rng = mulberry32(seed)
// for i in 0..n-1: levels[i] = floor(-ln(rng()) * mL)
}
Adapter mode: the level array is compared integer-exact (atol 0) to the reference, which uses the identical mulberry32 + formula + clamp. One stray PRNG call shifts every subsequent draw and fails the whole array.