Skip to content

rand

Terminal window
bun add @stopcock/rand

Deterministic random numbers. Same seed, same sequence, every time. Good for tests, simulations, and anything where you need reproducible results.

import { PCG, normal, shuffle } from '@stopcock/rand'
const rng = PCG.create(42)
const [value, next] = PCG.next(rng) // pure, returns new state
normal(0, 1, rng) // sample from N(0,1)
shuffle([1, 2, 3, 4, 5], rng)
import { PCG, shuffle, normal } from '@stopcock/rand'
// Same seed = same "random" data every time
let rng = PCG.create(12345)
const [shuffled, rng2] = shuffle(['Alice', 'Bob', 'Carol', 'Dave'], PCG, rng)
// Always: ['Carol', 'Alice', 'Dave', 'Bob']
const [score, rng3] = normal(PCG, 75, 10, rng2)
// Always: 82.3 (or whatever the deterministic output is)
import { PCG, weightedChoice } from '@stopcock/rand'
const loot = ['common', 'uncommon', 'rare', 'legendary']
const weights = [70, 20, 8, 2]
let rng = PCG.create(Date.now())
const [drop, next] = weightedChoice(loot, weights, PCG, rng)
import { PCG, uniform } from '@stopcock/rand'
let rng = PCG.create(42)
let inside = 0
const N = 100_000
for (let i = 0; i < N; i++) {
const [x, r1] = uniform(PCG, -1, 1, rng)
const [y, r2] = uniform(PCG, -1, 1, r1)
if (x * x + y * y <= 1) inside++
rng = r2
}
const pi = (4 * inside) / N // ≈ 3.14159

Two generator algorithms, both seedable and pure (return new state).

PCG.create(seed: number): PCGState
PCG.next(state: PCGState): [number, PCGState] // [0, 1) float + new state
PCG.nextInt(state: PCGState, min: number, max: number): [number, PCGState]
Xoshiro.create(seed: number): XoshiroState
Xoshiro.next(state: XoshiroState): [number, XoshiroState]
Xoshiro.nextInt(state: XoshiroState, min: number, max: number): [number, XoshiroState]
uniform(min: number, max: number, rng: PCGState | XoshiroState): [number, State]
normal(mean: number, stddev: number, rng: State): [number, State]
exponential(lambda: number, rng: State): [number, State]
poisson(lambda: number, rng: State): [number, State]
bernoulli(p: number, rng: State): [boolean, State]
shuffle<A>(arr: A[], rng: State): [A[], State]
sample<A>(arr: A[], k: number, rng: State): [A[], State]
weightedChoice<A>(items: [A, number][], rng: State): [A, State]