const bitIsSet = (num: number, pos: number) => (num & (1 << pos)) !== 0; export function encode(all: readonly T[], set: Set): number { let flags = 0; for (let i = 0; i < all.length; i++) { if (set.has(all[i] as T)) { flags |= 1 << i; } } return flags; } export function decode(all: readonly T[], flags: number): Set { const total = 2 ** all.length; if (flags < 0 || flags >= total) throw Error("invalid flags"); const decoded = new Set(); for (let j = 0; j < all.length; j++) { if (bitIsSet(flags, j)) decoded.add(all[j] as T); } return decoded; } export function* power(xs: readonly T[]) { const total = 2 ** xs.length; for (let i = 0; i < total; i++) { yield decode(xs, i); } } export function permutations(arr: readonly T[]): T[][] { if (arr.length === 0) return [[]]; const result: T[][] = []; for (let i = 0; i < arr.length; i++) { const current = arr[i]; const remaining = [...arr.slice(0, i), ...arr.slice(i + 1)]; for (const perm of permutations(remaining)) { result.push([current as T, ...perm]); } } return result; }