random / seeding / shuffle #1902
Replies: 2 comments
-
|
This is kind of the reason why I ended up implementing my own PRNG as it's then also possible ensure consistency across the targets: https://github.com/nicklasxyz/gleam_stats/blob/v1.1.0/src/gleam_stats/generators.gleam#L166-L166 Alg: https://www.pcg-random.org/ Aligning the functionality across the two platforms becomes a bit of a mess otherwise. |
Beta Was this translation helpful? Give feedback.
-
|
In case someone finds this looking for a solution to seed pub fn foo_test() {
seed("whatever")
// randomness is now deterministic
}
@external(javascript, "./helpers.js", "seed")
pub fn seed(str: String) -> Nil// Mostly copied from: https://stackoverflow.com/a/47593316
export function seed(str) {
const [a, b, c, d] = cyrb128(str);
const rand = sfc32(a, b, c, d);
// advance state a bit
for (var i = 0; i < 15; i++) rand();
Math.random = function () {
return rand();
};
}
function sfc32(a, b, c, d) {
return function () {
a |= 0;
b |= 0;
c |= 0;
d |= 0;
let t = (((a + b) | 0) + d) | 0;
d = (d + 1) | 0;
a = b ^ (b >>> 9);
b = (c + (c << 3)) | 0;
c = (c << 21) | (c >>> 11);
c = (c + t) | 0;
return (t >>> 0) / 4294967296;
};
}
function cyrb128(str) {
let h1 = 1779033703,
h2 = 3144134277,
h3 = 1013904242,
h4 = 2773480762;
for (let i = 0, k; i < str.length; i++) {
k = str.charCodeAt(i);
h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
h3 = h4 ^ Math.imul(h3 ^ k, 951274213);
h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);
}
h1 = Math.imul(h3 ^ (h1 >>> 18), 597399067);
h2 = Math.imul(h4 ^ (h2 >>> 22), 2869860233);
h3 = Math.imul(h1 ^ (h3 >>> 17), 951274213);
h4 = Math.imul(h2 ^ (h4 >>> 19), 2716044179);
((h1 ^= h2 ^ h3 ^ h4), (h2 ^= h1), (h3 ^= h1), (h4 ^= h1));
return [h1 >>> 0, h2 >>> 0, h3 >>> 0, h4 >>> 0];
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Caveat: This will rely on default args for good ergonomics
list.shuffleshould take an optional callback that can be used instead statically relying onfloat.random(0.0, 1.0).float.randomandint.randomto make it easier to generate slower but better values across the Erlang and Javascript by relying onrandom_floatandrandom_intfunctions togleam/erlangand maybegleam/javascriptthat allow to set a seeder and even constant seed values, for Erlang see: https://www.erlang.org/doc/man/rand.html#description -It seems https://www.erlang.org/doc/man/rand.html#seed-1 can use the value of https://www.erlang.org/doc/man/rand.html#export_seed-0 to capture and then return to the previous global state?
Beta Was this translation helpful? Give feedback.
All reactions