61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
export function shuffle<A>(subject: A[]): A[] {
|
|
const res = Array.from(subject);
|
|
|
|
for (let i = 0; i < res.length - 1; ++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 group<A>(subject: A[], keepTogether: A[][]): A[][] {
|
|
type Value = {array: A[], added: boolean};
|
|
|
|
const groups: Map<A, Value> = new Map;
|
|
for (const xs of keepTogether) {
|
|
const value = {array: xs, added: false};
|
|
for (const x of xs) { groups.set(x, value); }
|
|
}
|
|
|
|
const res = [];
|
|
|
|
for (const x of subject) {
|
|
const group = groups.get(x);
|
|
if (group?.added) { continue; }
|
|
else if (group) {
|
|
group.added = true;
|
|
res.push(shuffle(group.array));
|
|
} else {
|
|
res.push([x]);
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
export function groupedShuffle<A>(subject: A[], keepTogether: A[][]): A[] {
|
|
return shuffle(group(subject, keepTogether)).flat();
|
|
}
|
|
|
|
export function setup() {
|
|
const groups = [group('myno', 'abyss'), group('clip', 'cervine')];
|
|
|
|
for (const elem of Array.from(document.getElementsByClassName('shuffle'))) {
|
|
const shuffled = groupedShuffle(Array.from(elem.children), groups);
|
|
|
|
elem.innerHTML = '';
|
|
for (const child of shuffled) {
|
|
elem.appendChild(child);
|
|
}
|
|
}
|
|
|
|
function group(...xs: string[]) {
|
|
const elements = xs.map(x => document.getElementById(x));
|
|
return elements.every(x => x) ? elements as HTMLElement[] : [];
|
|
}
|
|
}
|