///|
const A : UInt64 = 1839567234
///|
const M : UInt64 = 8239451023
///|
const C : UInt64 = 972348567
///|
pub typealias State[UInt64, A] as RandomRNG[A]
///|
pub fn randomRng() -> RandomRNG[UInt64] {
State(fn(seed) {
let nextSeed = (A * seed + C) % M
(nextSeed, nextSeed)
})
}
///|
pub fn[A] random_with(gen : (UInt64) -> A) -> RandomRNG[A] {
State(fn(seed) {
let nextSeed = (A * seed + C) % M
(gen(nextSeed), nextSeed)
})
}
///|
pub fn random_double(min~ : Double = 0, max~ : Double = 1) -> RandomRNG[Double] {
random_with(fn(s) {
min + (s << 11 >> 11).to_double() / M.to_double() * (max - min)
})
}
///|
pub fn random_int(min : Int, max : Int) -> RandomRNG[Int] {
random_with(fn(s) {
min +
(s.to_double() / M.to_double() * (max - min).to_double()).floor().to_int()
})
}
// extern "js" fn now() -> UInt =
// #| Date.now()
///|
test "random" {
inspect((1).to_byte(), content="b'\\x01'")
inspect(
"12".to_bytes(),
content=
#|b"\x31\x00\x32\x00"
,
)
let rnd = @random.Rand::new()
inspect(rnd.int(limit=10), content="7")
inspect(rnd.int(limit=10), content="0")
inspect(rnd.int(limit=10), content="5")
inspect(rnd.int(limit=10), content="4")
inspect(random_int(0, 10).evaluate(123), content="5")
inspect(random_int(0, 10).evaluate(1234), content="6")
inspect(random_int(0, 10).evaluate(12345), content="3")
inspect(random_int(0, 10).evaluate(123456), content="3")
inspect(random_int(0, 10).evaluate(1234567), content="6")
inspect(random_int(0, 10).evaluate(12345678), content="2")
inspect(random_int(0, 10).evaluate(123456789), content="3")
}