Switch to a hash-based shuffle so adding new items won't change the shuffled order of existing items
This commit is contained in:
parent
cf17ec85a7
commit
bede558347
1 changed files with 28 additions and 23 deletions
|
@ -1,31 +1,36 @@
|
||||||
const LCG_M = Math.pow(2, 32);
|
// cyrb53a beta (c) 2023 bryc (github.com/bryc)
|
||||||
const LCG_A = 0xd9f5;
|
function cyrb53a_beta(str, seed = 0) {
|
||||||
const LCG_C = 69;
|
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
||||||
|
for (const codePoint of str) {
|
||||||
function lcg(seed) {
|
ch = codePoint.codePointAt(0);
|
||||||
let value = seed % LCG_M;
|
h1 = Math.imul(h1 ^ ch, 0x85ebca77);
|
||||||
|
h2 = Math.imul(h2 ^ ch, 0xc2b2ae3d);
|
||||||
return (n) => {
|
}
|
||||||
value = (LCG_A * value + LCG_C) % LCG_M;
|
h1 ^= Math.imul(h1 ^ (h2 >>> 15), 0x735a2d97);
|
||||||
return Math.floor(n * value / LCG_M);
|
h2 ^= Math.imul(h2 ^ (h1 >>> 15), 0xcaf649a9);
|
||||||
};
|
h1 ^= h2 >>> 16;
|
||||||
|
h2 ^= h1 >>> 16;
|
||||||
|
return 2097152 * (h2 >>> 0) + (h1 >>> 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
function seedableShuffledCopy(list, seed) {
|
const SEED_BOUND = Math.pow(2, 32);
|
||||||
const gen = lcg(seed);
|
|
||||||
const l = [...list];
|
|
||||||
|
|
||||||
for (let i = 0; i < l.length - 1; ++i) {
|
function seedableShuffledCopy(list, key, seed) {
|
||||||
j = i + gen(l.length - i);
|
const hashedIndices = list.map((elem, idx) => ({ idx, hash: cyrb53a_beta(key(elem), seed) }));
|
||||||
const tmp = l[i];
|
hashedIndices.sort((a, b) => {
|
||||||
l[i] = l[j];
|
if (a.hash > b.hash) {
|
||||||
l[j] = tmp;
|
return 1;
|
||||||
}
|
}
|
||||||
return l;
|
if (a.hash < b.hash) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
return hashedIndices.map((entry) => list[entry.idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function newSeed() {
|
function newSeed() {
|
||||||
return Math.floor(Math.random() * LCG_M);
|
return Math.floor(Math.random() * SEED_BOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
let receivedStore = JSON.parse(localStorage.getItem('receivedStore')) || {};
|
let receivedStore = JSON.parse(localStorage.getItem('receivedStore')) || {};
|
||||||
|
@ -96,7 +101,7 @@ function setupIndex() {
|
||||||
|
|
||||||
switch (ordering) {
|
switch (ordering) {
|
||||||
case 'shuffle':
|
case 'shuffle':
|
||||||
orderedWorks = seedableShuffledCopy(WORKS, shuffleSeed);
|
orderedWorks = seedableShuffledCopy(WORKS, (work) => work.id, shuffleSeed);
|
||||||
break;
|
break;
|
||||||
case 'dateAsc':
|
case 'dateAsc':
|
||||||
orderedWorks = WORKS.toReversed();
|
orderedWorks = WORKS.toReversed();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue