Constellations/js/Solver/Inclusion.js

84 lines
2.1 KiB
JavaScript
Raw Normal View History

2022-08-19 08:19:50 +02:00
import * as CellSet from Geometry.CellSet;
import * as Strategy from Solver.Strategy;
import {getColumn, getRow} from Geometry.Vector;
2022-08-30 22:39:09 +02:00
import Set;
2022-08-19 08:19:50 +02:00
return {
find: find
};
2022-08-30 22:39:09 +02:00
function find(solvingState) {
var inclusion = findInclusion(cellDimensionsByname(solvingState));
return Strategy.tryEach([
inclusion('rows', 'colors'),
inclusion('columns', 'colors'),
inclusion('colors', 'rows'),
inclusion('colors', 'columns')
]);
2022-08-19 08:19:50 +02:00
}
2022-08-30 22:39:09 +02:00
function cellDimensionsByname(solvingState) {
return {
rows: {sets: solvingState.rows, property: getRow},
columns: {sets: solvingState.columns, property: getColumn},
colors: {sets: solvingState.colorZones, property: solvingState.getColor}
};
}
function getAll(property) {
return function(cellSet) {return new Set.Int(cellSet.map(property));};
}
function getSet(namedSet) {
return function(i) {return namedSet.sets[i];};
2022-08-19 08:19:50 +02:00
}
2022-08-30 22:39:09 +02:00
function findInclusion(cellDimensions) {
return function(subName, superName) {
var subDimension = cellDimensions[subName];
var superDimension = cellDimensions[superName];
var diff = difference(getSet(subDimension), getSet(superDimension));
return Strategy.map(
stepOfInclusion(subName, superName),
Strategy.tryEach(
group(subDimension.sets.map(getAll(superDimension.property))).map(diff)
)
);
}
}
function difference(getSubset, getSuperset) {
return function(group) {
2022-08-19 08:19:50 +02:00
return function() {
2022-08-30 22:39:09 +02:00
if(group.indices.length == group.value.size()) {
var empty = CellSet.union(group.value.map(getSuperset))
.difference(CellSet.union(group.indices.map(getSubset)));
return empty.size() > 0 ? {empty: empty, group: group} : null;
2022-08-19 08:19:50 +02:00
}
};
};
}
2022-08-30 22:39:09 +02:00
function stepOfInclusion(subName, superName) {
return function(diffedGroup) {
var step = {reason: 'inclusion', empty: diffedGroup.empty};
step[subName] = diffedGroup.group.indices;
step['in_' + superName] = diffedGroup.group.value.toList();
return step;
2022-08-19 08:19:50 +02:00
};
}
2022-08-30 22:39:09 +02:00
function group(sets) {
var groups = [];
sets.forEach(function(set, i) {
for(var g = 0; g < groups.length; g++) {
if(groups[g].value.equals(set)) {
groups[g].indices.push(i);
2022-08-19 08:19:50 +02:00
return;
}
}
2022-08-30 22:39:09 +02:00
groups.push({value: set, indices: [i]});
2022-08-19 08:19:50 +02:00
});
2022-08-30 22:39:09 +02:00
return groups;
2022-08-19 08:19:50 +02:00
}