83 lines
2.2 KiB
JavaScript
83 lines
2.2 KiB
JavaScript
import * as CellSet from Geometry.CellSet;
|
|
import * as Strategy from Solver.Strategy;
|
|
import {getColumn, getRow} from Geometry.Vector;
|
|
import Set;
|
|
|
|
return {
|
|
find: find
|
|
};
|
|
|
|
function find(solvingState) {
|
|
var inclusion = findInclusion(cellDimensionsByName(solvingState));
|
|
return Strategy.tryEach([
|
|
inclusion('rows', 'colors'),
|
|
inclusion('columns', 'colors'),
|
|
inclusion('colors', 'rows'),
|
|
inclusion('colors', 'columns')
|
|
]);
|
|
}
|
|
|
|
function cellDimensionsByName(solvingState) {
|
|
return {
|
|
rows: {sets: solvingState.zones.rows, property: getRow},
|
|
columns: {sets: solvingState.zones.columns, property: getColumn},
|
|
colors: {sets: solvingState.zones.colors, 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];};
|
|
}
|
|
|
|
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) {
|
|
return function() {
|
|
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;
|
|
}
|
|
};
|
|
};
|
|
}
|
|
|
|
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;
|
|
};
|
|
}
|
|
|
|
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);
|
|
return;
|
|
}
|
|
}
|
|
groups.push({value: set, indices: [i]});
|
|
});
|
|
return groups;
|
|
}
|