"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.diceZones = diceZones;
exports.hashZone = hashZone;
function* diceZones(dn, zoneSets) {
    if (!zoneSets.length)
        return;
    yield* scanPlaneDiceZones(dn, 0, [], zoneSets);
}
function* scanPlaneDiceZones(dn, d, carry, zones) {
    if (d >= dn) {
        yield fetchMatchingSs(carry, zones);
        return;
    }
    const stops = new Set();
    for (const [zone] of zones) {
        let shouldInclude = true;
        for (let dt = 0; dt < d; dt++) {
            const spanZone = zone[dt];
            const spanCarry = carry[dt];
            if (spanCarry[0] < spanZone[0] || spanCarry[1] > spanZone[1]) {
                shouldInclude = false;
                break;
            }
        }
        if (shouldInclude) {
            stops.add(zone[d][0]);
            stops.add(zone[d][1]);
        }
    }
    const sortedStops = Array.from(stops).sort(asc);
    for (let s = 1; s < sortedStops.length; s++) {
        carry[d] = [sortedStops[s - 1], sortedStops[s]];
        yield* scanPlaneDiceZones(dn, d + 1, carry, zones);
    }
}
function fetchMatchingSs(carry, zones) {
    const matchingSSet = [];
    for (const [srcZone, s] of zones) {
        let inZone = true;
        for (let d = 0; d < srcZone.length; d += 1) {
            if (carry[d][0] < srcZone[d][0] || carry[d][1] > srcZone[d][1]) {
                inZone = false;
                break;
            }
        }
        if (inZone)
            matchingSSet.push(s);
    }
    return [carry.slice(0), matchingSSet];
}
function asc(a, b) {
    return a - b;
}
function hashZone(zone) {
    let result = "";
    for (let d = 0; d < zone.length; d++) {
        result += `${zone[d][0]};${zone[d][1]}/`;
    }
    return result;
}
//# sourceMappingURL=zone-dicing.js.map