Build your own vector database
Setup & the O(N) wall·8 min

L2 distance

0 / 1
# grade this stage (from your course directory)
npx theinference test --stage l2-distance --watch

Every comparison HNSW makes is a distance. We use squared L2 (Euclidean) distance — the field standard for SIFT-style vectors. This is your first green check, and the function the whole index is built on.

Squared L2
l2(a, b) = Σ (aᵢ - bᵢ)²        // note: NO square root
Return squared L2, not the square root

Distance comparisons only need ordering, and √ is monotonically increasing — skipping it never changes which vector is nearer, and it saves a sqrt on every comparison. Our ground truth is computed the same way, so return Σ(aᵢ-bᵢ)² directly. (The upstream ANN-Benchmarks data stores true L2 with the root, but since √ is monotonic the neighbor indices — what recall is scored on — are identical either way.)

Keep the comparison counter wired

l2() increments a global COMPARISONS counter on every call. Do not remove it: later chapters grade mean comparisons per query against a frozen budget, which is the anti-cheat that rejects a brute-force solution. Use the provided bumpComparisons() (or increment COMPARISONS directly) at the top of l2().

What to build

Your task

Implement runL2

Implement l2(a, b) in src/distance.ts, then expose it through runL2(a, b) in tests/adapters.ts. Both a and b are equal-length number arrays; return a single number, squared L2.

tests/adapters.ts
export function runL2(a: number[], b: number[]): number[] {
  // return [ squared L2 distance ]  — a one-element array
}
How it's graded

Adapter mode: your returned [value] is compared to the reference with allclose, atol 1e-4, rtol 1e-3. Scalars are returned as a one-element array — the harness flattens it to shape [1].