yummy.cricket/script/shuffle.ts

66 lines
1.5 KiB
TypeScript

function group<A>(subject: A[], keepTogether: A[][]): A[][] {
type Value = {array: A[], added: boolean};
let groups: Map<A, Value> = new Map;
for (const xs of keepTogether) {
let value = {array: xs, added: false};
for (const x of xs) { groups.set(x, value); }
}
let res = [];
for (const x of subject) {
let group = groups.get(x);
if (group?.added) { continue; }
else if (group) {
group.added = true;
res.push(group.array);
} else {
res.push([x]);
}
}
return res;
}
function shuffle<A>(subject: A[]): A[] {
let res = Array.from(subject);
for (let i = 0; i < res.length - 2; ++i) {
const j = i + Math.floor(Math.random() * (res.length - i));
if (i != j) {
const k = res[i]!;
res[i] = res[j]!;
res[j] = k;
}
}
return res;
}
function groupedShuffle<A>(subject: A[], keepTogether: A[][]): A[] {
let groups = group(subject, keepTogether);
return shuffle(groups).flat();
}
function shuffleAll() {
let groups = [group('myno', 'abyss'), group('clip', 'cervine')];
for (const elem of Array.from(document.getElementsByClassName('shuffle'))) {
let shuffled = groupedShuffle(Array.from(elem.children), groups);
elem.innerHTML = '';
for (const child of shuffled) {
elem.appendChild(child);
}
}
function group(...xs: string[]) {
let elements = xs.map(x => document.getElementById(x));
return elements.every(x => x) ? elements as HTMLElement[] : [];
}
}
document.addEventListener('DOMContentLoaded', shuffleAll);
export {};