Skip to content

Commit 3bef31f

Browse files
committed
refactor: deterministic shuffle algorithm
1 parent f2dc41b commit 3bef31f

File tree

1 file changed

+19
-9
lines changed
  • apps/site/components/Common/Partners

1 file changed

+19
-9
lines changed

apps/site/components/Common/Partners/utils.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,24 @@ import type {
55
Partners,
66
} from '#site/types/partners.js';
77

8+
// Fisher-Yates shuffle algorithm with a seed for deterministic results
9+
function shuffle(array: Array<Partners>, seed: number): Array<Partners> {
10+
const shuffled = [...array];
11+
const hash = crypto.createHash('sha256').update(String(seed)).digest();
12+
13+
for (let i = shuffled.length - 1; i > 0; i--) {
14+
// Use hash bytes to generate deterministic "random" index
15+
const hashIndex = (i + seed) % 32;
16+
// Normalize to 0-1
17+
const randomValue = hash[hashIndex] / 255;
18+
19+
const j = Math.floor(randomValue * (i + 1));
20+
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
21+
}
22+
23+
return shuffled;
24+
}
25+
826
function randomPartnerList(
927
partners: Array<Partners>,
1028
config: RandomPartnerListConfig
@@ -19,15 +37,7 @@ function randomPartnerList(
1937
? partners.filter(p => p.categories.includes(category))
2038
: partners;
2139

22-
// Create a hash from the seed to use for consistent randomization
23-
const hash = crypto.createHash('sha256').update(String(seed)).digest();
24-
25-
// Sort partners using the hash to ensure same results for the same seed
26-
const sorted = filtered.sort(
27-
(a, b) => hash[a.name.charCodeAt(0) % 32] - hash[b.name.charCodeAt(0) % 32]
28-
);
29-
30-
return sorted.slice(0, pick ?? sorted.length);
40+
return shuffle(filtered, seed).slice(0, pick ?? filtered.length);
3141
}
3242

3343
export { randomPartnerList };

0 commit comments

Comments
 (0)