Orthogonal stream prime generators — Algorithms A, B and C of algorithm.md, one module each

Each algorithm is a single self-contained ES module — no build step, nothing loaded from the network. algorithm-a.js: exact one-touch streams Σ_b = { b·q : q ≥ P(b) }, every composite popped exactly once, S(N) ≈ N^0.75 live streams (§3). algorithm-b.js: wheeled streams p·Ã_p, O(1) state per prime, π(√n) records, O(1) segment restart (§4). algorithm-c.js: the same wheel re-indexed by the min-factor normal form m = p^e·r, emitting (spf, v_p, cofactor) for every rejected candidate (§4C, min_factor.md). Shared plumbing — wheel tables, min-heap, reference sieve — is in primegen-core.js. Serve this folder over http: ES modules do not load from file://.

Generate §3.4 / §4.3 / §4C.2 — unbounded stream, bounded driver

w is the number of wheel primes (Algorithms B and C only); W = p₁···p_w, κW = φ(W)/W is the candidate density. Primes ≤ p_w are emitted directly and their composites never become candidates. Algorithm A uses no wheel at all.

log

Number spiral consume the generated primes — factorisation field on a square (Ulam) or hexagonal spiral

square: primes ≤ , side L = ⌊√N⌋ (capped at 8192), laid out on the classic Ulam spiral. hexagonal: primes ≤ 1+3R(R+1) walked around a hex ring spiral (ring k holds 6k cells, consecutive integers are always neighbours), stored in an axial (2R+1)² grid and drawn by nearest-hex sampling.

linear slice: no spiral at all — the integers are written left-to-right, row by row, into a slice whose rows grow linearly: the top row holds one cell and row k holds ⌊1 + δ·k⌋ cells, so after R rows the plot covers R + δ·R(R−1)/2 integers. δ therefore selects the quadratic projection: δ = 2 gives the odd rows 1, 3, 5, … and exactly integers (Ulam's rings unrolled), δ = 1 the triangular numbers, δ = 0 a single column, fractional δ everything in between. Rows can aligned left, centre or right inside the bounding box; cells outside the slice stay background. Because a row is an arithmetic progression, the vertical striping of the field is the residue structure mod the row width. Hovering a cell in this mode also reports the whole column under the cursor: the quadratic n(k) = (δ/2)k² + βk + γ that generates it (exact when the floors are harmless, otherwise the closed form), its row range, and the min / avg / max of ω, Ω, sopfr and sopfr/n together with the prime count along the column.

Every cell is coloured, not just the primes: the spiral carries the factorisation field of n. Hue = ω(n), the number of distinct prime factors — ω = 1 (primes and prime powers) is gold, rising ω sweeps green → cyan → blue → magenta. HSL lightness = sopfr(n)/n, the sum of the prime factors with multiplicity divided by n. Since sopfr(n) ≤ n with equality exactly when n is prime (and at n = 4), the primes are the maxima of the field at value 1, while n = 2p sits at ≈1/2, n = 3p at ≈1/3, … — each composite lands on the ray of its smallest factor, so the spiral shows the arithmetic structure around the primes instead of a bare dot mask. Zoomed in the exact per-cell field is sampled; zoomed out a pre-computed mip pyramid of sums Σ1, Σω, ΣΩ, Σ sopfr/n is used and converted to RGB only at the end, so neither a prime nor a hue is ever dropped by nearest-neighbour downscaling. n₀ truncates the spiral at the origin — the centre cell may start counting at 0, 1, 2 or 3. Drag to pan · wheel to zoom · hover for the factorisation · reset to fit.

Legend: x = ω(n) (hue), y = sopfr(n)/n (lightness). The top-left corner — gold at full lightness — is the prime locus; the horizontal bands at 1/2, 1/3, 1/5 … are 2p, 3p, 5p; increasing hue means more distinct prime factors, and the dark right-hand region is the smooth-number bulk.