|
| 1 | +const mulberry32 = (a: number) => () => { |
| 2 | + let t = (a += 0x6d2b79f5); |
| 3 | + t = Math.imul(t ^ (t >>> 15), t | 1); |
| 4 | + t ^= t + Math.imul(t ^ (t >>> 7), t | 61); |
| 5 | + return ((t ^ (t >>> 14)) >>> 0) / 4294967296; |
| 6 | +}; |
| 7 | + |
| 8 | +const cyrb53 = (str: string, seed = 0) => { |
| 9 | + let h1 = 0xdeadbeef ^ seed, |
| 10 | + h2 = 0x41c6ce57 ^ seed; |
| 11 | + for (let i = 0, ch; i < str.length; i++) { |
| 12 | + ch = str.charCodeAt(i); |
| 13 | + h1 = Math.imul(h1 ^ ch, 2654435761); |
| 14 | + h2 = Math.imul(h2 ^ ch, 1597334677); |
| 15 | + } |
| 16 | + h1 = |
| 17 | + Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ |
| 18 | + Math.imul(h2 ^ (h2 >>> 13), 3266489909); |
| 19 | + h2 = |
| 20 | + Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ |
| 21 | + Math.imul(h1 ^ (h1 >>> 13), 3266489909); |
| 22 | + return 4294967296 * (2097151 & h2) + (h1 >>> 0); |
| 23 | +}; |
| 24 | + |
| 25 | +function shuffle<T>(array: T[], seed: number | string = 0) { |
| 26 | + if (typeof seed === 'string') { |
| 27 | + seed = cyrb53(seed); |
| 28 | + } |
| 29 | + const random = mulberry32(seed); |
| 30 | + |
| 31 | + const output = new Array(array.length); |
| 32 | + |
| 33 | + for (let i = 0; i < array.length; i++) { |
| 34 | + output[i] = array[i]; |
| 35 | + } |
| 36 | + |
| 37 | + let m = output.length; |
| 38 | + |
| 39 | + while (m) { |
| 40 | + const i = Math.floor(random() * m--); |
| 41 | + |
| 42 | + const t = output[m]; |
| 43 | + output[m] = output[i]; |
| 44 | + output[i] = t; |
| 45 | + ++seed; |
| 46 | + } |
| 47 | + |
| 48 | + return output; |
| 49 | +} |
| 50 | + |
| 51 | +export default shuffle; |
0 commit comments