export function askNumber(promptText, initValue, promptCallback, resolver) { const promptValueStr = promptCallback(promptText, initValue); if (promptValueStr != null) { let promptValue = Number(promptValueStr); if (promptValue == promptValue) { // check for NaN return promptValue; } else { if (!!resolver) { promptValue = resolver(promptValueStr); if (promptValue == promptValue) { return promptValueStr; } } } } return null; } export function constRef(value) { return function() { return value; }; } export function swap(arr, i1, i2) { const tmp = arr[i1]; arr[i1] = arr[i2]; arr[i2] = tmp; } export function defineIterable(obj, name, iteratorFactory) { obj[name] = {}; obj[name][Symbol.iterator] = iteratorFactory; } export class DoubleKeyMap { constructor() { this.map = new Map(); } get(a, b) { let subMap = this.map.get(a); if (subMap == null) { subMap = this.map.get(b); if (subMap != null) { return subMap.get(a); } return null; } return subMap.get(b); } set(a, b, value) { let subMap = this.map.get(a); if (subMap == null) { subMap = this.map.get(b); if (subMap != null) { subMap.set(a, value); return; } subMap = new Map(); this.map.set(a, subMap); } subMap.set(b, value); } } export function reversedIndex(i, n) { let lidIdx = n - i; if (lidIdx == n) { lidIdx = 0; } return lidIdx; } export function rotateArr(arr, pivot) { function reverse(arr, from, to) { to --; while (from < to) { const t = arr[from]; arr[from] = arr[to]; arr[to] = t; from ++; to --; } } reverse(arr, 0, pivot); reverse(arr, pivot, arr.length); reverse(arr, 0, arr.length); }