det
Deterministic PRNG and sort utilities - seeded LCG integer mixing, bounded random integers, pick one element from a list, Fisher-Yates shuffle, FNV-1a string hashing, hash-keyed sort, deterministic sampling, and stable deduplication. All outputs are reproducible from the same seed.
Load with: use det
What this module does
det provides deterministic pseudo-randomness and ordering primitives.
Unlike cry.cryrn or system randomness, every function in det
produces the same output for the same seed - making it ideal for reproducible tests,
procedural generation, stable test-data shuffling, and consistent sampling.
The core is a 32-bit LCG (linear congruential generator): x * 1664525 + 1013904223,
the same constants as Numerical Recipes. String hashing uses FNV-1a (32-bit) for
stable ordering keys. The det.mix alias is used by other stdlib modules
(e.g. c2 for jitter) to produce deterministic offsets.
Quick example
use det
# Deterministic integer mix
prn(detmi(42)) # always the same value
# Seeded integer from seed + salt
prn(detin(1234, 7))
# Pick one element from a list
items = ["a", "b", "c", "d"]
prn(detpi(items, 99)) # reproducible choice
# Shuffle a list (Fisher-Yates, seeded)
shuffled = detsh(items, 42)
# Bounded random integer in [0, 10)
prn(detbe(42, 0, 10))
# Hash a string to a stable integer
prn(detha("hello")) # always the same FNV-1a hash
# Sort a list in deterministic hash order
prn(detso(["banana", "apple", "cherry"]))
# Sample k elements in deterministic order
prn(detsa(items, 42, 2))
# Deduplicate (stable, hash-keyed)
prn(detun(["a", "b", "a", "c"]))
Functions
PRNG core
detmi(n)
LCG mix: applies x = x * 1664525 + 1013904223 to the integer n and returns the absolute value. This is the basic mixing step. Also exposed as det.mix.
detin(seed, salt)
Generates a deterministic integer from a seed and salt by mixing seed + salt * 374761393. Use different salt values to get independent streams from the same seed.
Selection and shuffling
detpi(list, seed)
Picks one element from a list deterministically using detin(seed, 0) % len(list). Errors if the list is empty.
detsh(list, seed)
Returns a shuffled copy of the list using the Fisher-Yates algorithm, deriving each swap index from detin(seed, j). The original list is not modified.
detbe(seed, salt, hi)
Returns a deterministic integer in [0, hi). Errors if hi ≤ 0.
detra(n)
Returns the list [0, 1, 2, …, n-1]. Useful as input to other det functions.
Hashing and sorting
detha(s)
FNV-1a 32-bit hash of string s. Produces a stable non-negative integer. Used internally for hash-keyed sorting and deduplication. Not cryptographically secure.
detso(list)
Sorts a copy of the list by the FNV-1a hash of each element's string representation. The output order is deterministic and independent of input order. Uses an internal bubble sort on keyed records.
Sampling and deduplication
detsa(list, seed, k)
Returns the first k elements of a seeded shuffle of the list. Effectively a deterministic sample without replacement. Returns all elements if k ≥ len(list).
detun(list)
Returns a deduplicated copy of the list. Equality is determined by the FNV-1a hash of each element's string form - so any two elements that produce the same string are considered duplicates. Preserves first-seen order.
Notes
- All operations are deterministic - same seed and input always produce the same output.
- Not suitable for cryptographic use. For secure randomness use
cry.cryrn. - The
det.mixalias is the only exported namespace value; all other functions are top-level. - Requires
trl,txt, anderu.