"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shuffle = exports.shuffleInplace = exports.max = exports.min = exports.sum = exports.reorder = exports._matchAllExc = exports.matchAllExc = exports.matchAll = exports.repeatArray = exports.rangeArray = exports.pop = exports.butLast = exports.last = exports.lastIndex = exports.unshift = exports.insert = exports.push = exports.pull = exports.remove = exports.removeAt = exports.at = exports.rotate = exports.reduce = exports.forEach = void 0;
function forEach(array, callback) {
    array.forEach(callback);
}
exports.forEach = forEach;
function reduce(array, acc, callback) {
    return array.reduce(callback, acc);
}
exports.reduce = reduce;
// https://stackoverflow.com/questions/1985260/javascript-array-rotate
function rotate(array, count) {
    const len = array.length >>> 0; // convert to uint
    count = count >> 0; // convert to int
    // convert count to value in range [0, len)
    count = ((count % len) + len) % len;
    array.push(...array.splice(0, count));
    return array;
}
exports.rotate = rotate;
function at(array, index) {
    return array[index];
}
exports.at = at;
function removeAt(array, index) {
    array.splice(index, 1);
}
exports.removeAt = removeAt;
function remove(array, element) {
    const index = array.indexOf(element);
    removeAt(array, index);
}
exports.remove = remove;
function pull(array, element) {
    const index = array.indexOf(element);
    removeAt(array, index);
}
exports.pull = pull;
function push(array, element) {
    array.push(element);
}
exports.push = push;
function insert(array, element, at) {
    array.splice(at, 0, element);
    return array;
}
exports.insert = insert;
function unshift(array, ...elements) {
    return array.unshift(...elements);
}
exports.unshift = unshift;
function lastIndex(array) {
    const _lastIndex = array.length - 1;
    return _lastIndex;
}
exports.lastIndex = lastIndex;
function last(array) {
    const _lastIndex = lastIndex(array);
    const _last = array[_lastIndex];
    return _last;
}
exports.last = last;
function butLast(array) {
    const _butLast = array.slice(0, -1);
    return _butLast;
}
exports.butLast = butLast;
function pop(array) {
    const l = array.length;
    const last = array[l - 1];
    const rest = array.slice(0, l - 1);
    return [last, rest];
}
exports.pop = pop;
function rangeArray(n) {
    const array = [];
    for (let i = 0; i < n; i++) {
        array.push(i);
    }
    return array;
}
exports.rangeArray = rangeArray;
function repeatArray(n, value) {
    const array = [];
    for (let i = 0; i < n; i++) {
        array.push(value);
    }
    return array;
}
exports.repeatArray = repeatArray;
function matchAll(a, b, match) {
    const all = [];
    for (let i = 0; i < a.length; i++) {
        const ai = a[i];
        for (let j = 0; j < b.length; j++) {
            const bi = b[j];
            if (match(ai, bi)) {
                all.push([i, j]);
            }
        }
    }
    return all;
}
exports.matchAll = matchAll;
function indexSet(a) {
    return new Set(rangeArray(a.length));
}
// exclusive
function matchAllExc(a, b, match) {
    return _matchAllExc(a, b, indexSet(a), indexSet(b), [], match);
}
exports.matchAllExc = matchAllExc;
function _matchAllExc(a, b, _a, _b, _all, match) {
    let all = [];
    for (let i of _a) {
        const ai = a[i];
        for (let j of _b) {
            const bi = b[j];
            if (match(ai, bi)) {
                const __a = new Set(_a);
                const __b = new Set(_b);
                __a.delete(i);
                __b.delete(j);
                const other = _matchAllExc(a, b, __a, __b, _all, match);
                if (other.length > 0) {
                    for (const x of other) {
                        all.push([[i, j], ...x]);
                    }
                }
                else {
                    all.push([..._all, [i, j]]);
                }
            }
        }
    }
    return all;
}
exports._matchAllExc = _matchAllExc;
function reorder(array, element, to) {
    remove(array, element);
    insert(array, element, to);
}
exports.reorder = reorder;
function sum(array) {
    return array.reduce((acc, value) => acc + value, 0);
}
exports.sum = sum;
function min(array) {
    return array.reduce((acc, value) => Math.min(acc, value), Infinity);
}
exports.min = min;
function max(array) {
    return array.reduce((acc, value) => Math.max(acc, value), -Infinity);
}
exports.max = max;
function shuffleInplace(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        const temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}
exports.shuffleInplace = shuffleInplace;
function shuffle(array) {
    const shuffledArray = [...array];
    for (let i = shuffledArray.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [shuffledArray[i], shuffledArray[j]] = [shuffledArray[j], shuffledArray[i]];
    }
    return shuffledArray;
}
exports.shuffle = shuffle;
//# sourceMappingURL=index.js.map