[WIP, BROKEN] attempt to factorize zone handling to provide tooling to detect contradictions in hypothesis solver (zones becoming empty which shouldn't)
This commit is contained in:
parent
c411ffbcac
commit
fb0c655089
4 changed files with 64 additions and 31 deletions
|
@ -21,6 +21,7 @@ function make(type) {
|
||||||
Set.prototype.remove = function(e) { delete this.elements[type.toKey(e)]; };
|
Set.prototype.remove = function(e) { delete this.elements[type.toKey(e)]; };
|
||||||
Set.prototype.contains = function(e) { return !!this.elements[type.toKey(e)]; };
|
Set.prototype.contains = function(e) { return !!this.elements[type.toKey(e)]; };
|
||||||
Set.prototype.size = function() { return Object.keys(this.elements).length; };
|
Set.prototype.size = function() { return Object.keys(this.elements).length; };
|
||||||
|
Set.prototype.copy = function() { return new Set(this.toList()); };
|
||||||
|
|
||||||
Set.prototype.toList = function() {
|
Set.prototype.toList = function() {
|
||||||
var result = [];
|
var result = [];
|
||||||
|
|
10
js/Solver.js
10
js/Solver.js
|
@ -39,16 +39,8 @@ function applyStep(solvingState) {
|
||||||
console.log(step);
|
console.log(step);
|
||||||
['empty', 'star'].forEach(function(attribute) {
|
['empty', 'star'].forEach(function(attribute) {
|
||||||
if(step[attribute] != undefined) {
|
if(step[attribute] != undefined) {
|
||||||
step[attribute].iter(function(cell) {
|
step[attribute].iter(State.setCell(solvingState, attribute == 'star'));
|
||||||
set(solvingState.constellation, cell, attribute == 'star');
|
|
||||||
forget(solvingState, cell);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function forget(solvingState, cell) {
|
|
||||||
State.getCellSets(solvingState).concat(solvingState.missing)
|
|
||||||
.forEach(function(cellSet) {cellSet.remove(cell);});
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
import * as CellSet from Geometry.CellSet;
|
import * as CellSet from Geometry.CellSet;
|
||||||
import getCellSets from Solver.State;
|
|
||||||
import * as Strategy from Solver.Strategy;
|
import * as Strategy from Solver.Strategy;
|
||||||
import {diagonal, getColumn, getRow, plus} from Geometry.Vector;
|
import {diagonal, getColumn, getRow, plus} from Geometry.Vector;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
find: find
|
find: find,
|
||||||
|
perimeter: perimeter
|
||||||
};
|
};
|
||||||
|
|
||||||
function find(solvingState) {
|
function find(solvingState) {
|
||||||
var cellSets = getCellSets(solvingState);
|
|
||||||
return Strategy.map(
|
return Strategy.map(
|
||||||
stepOfCell(solvingState.missing),
|
stepOfCell(solvingState.missing),
|
||||||
Strategy.tryEach(cellSets.map(getSingleCellIn))
|
Strategy.tryEach(solvingState.colorZones.map(getSingleCellIn))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,13 +26,13 @@ function stepOfCell(missing) {
|
||||||
return function(cell) {
|
return function(cell) {
|
||||||
return {
|
return {
|
||||||
reason: 'singleCell',
|
reason: 'singleCell',
|
||||||
empty: toEmpty(cell).intersection(missing),
|
empty: perimeter(cell).intersection(missing),
|
||||||
star: new CellSet.CellSet(cell)
|
star: new CellSet.CellSet(cell)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function toEmpty(cell) {
|
function perimeter(cell) {
|
||||||
var union = CellSet.union([
|
var union = CellSet.union([
|
||||||
CellSet.rectangle(plus(cell, diagonal(-1)), diagonal(3)),
|
CellSet.rectangle(plus(cell, diagonal(-1)), diagonal(3)),
|
||||||
CellSet.row(getRow(cell)),
|
CellSet.row(getRow(cell)),
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
|
import id from UnitJS.Fun;
|
||||||
import size from Config;
|
import size from Config;
|
||||||
import {asAFunction, iter, square} from Grid.Util;
|
import {asAFunction, iter, map, set, square} from Grid.Util;
|
||||||
import {diagonal, zero} from Geometry.Vector;
|
import {diagonal, zero} from Geometry.Vector;
|
||||||
import * as CellSet from Geometry.CellSet;
|
import * as CellSet from Geometry.CellSet;
|
||||||
|
|
||||||
|
var zoneNames = ['colors', 'rows', 'columns'];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getCellSets: getCellSets,
|
setCell: setCell,
|
||||||
start: start
|
start: start,
|
||||||
|
fork: fork
|
||||||
};
|
};
|
||||||
|
|
||||||
function start(coloring) {
|
function start(coloring) {
|
||||||
|
@ -14,25 +18,62 @@ function start(coloring) {
|
||||||
constellation: square(size),
|
constellation: square(size),
|
||||||
getColor: asAFunction(coloring),
|
getColor: asAFunction(coloring),
|
||||||
missing: CellSet.rectangle(zero(), diagonal(size)),
|
missing: CellSet.rectangle(zero(), diagonal(size)),
|
||||||
colorZones: getZones(coloring),
|
zones: {
|
||||||
|
colors: getColors(coloring),
|
||||||
rows: empty.map(function(_, i) {return CellSet.row(i);}),
|
rows: empty.map(function(_, i) {return CellSet.row(i);}),
|
||||||
columns: empty.map(function(_, i) {return CellSet.column(i);})
|
columns: empty.map(function(_, i) {return CellSet.column(i);})
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getZones(grid) {
|
function getColors(grid) {
|
||||||
var zones = Array.from({length: size});
|
var colors = Array.from({length: size});
|
||||||
iter(grid, function(color, cell) {
|
iter(grid, function(color, cell) {
|
||||||
if(zones[color] == undefined) {
|
if(colors[color] == undefined) {
|
||||||
zones[color] = new CellSet.CellSet();
|
colors[color] = new CellSet.CellSet();
|
||||||
}
|
}
|
||||||
zones[color].add(cell);
|
colors[color].add(cell);
|
||||||
});
|
});
|
||||||
return zones;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCellSets(solvingState) {
|
function fork(state) {
|
||||||
return solvingState.colorZones
|
var zones = {};
|
||||||
.concat(solvingState.rows)
|
zoneNames.forEach(function(name) {
|
||||||
.concat(solvingState.columns);
|
zones[name] = state.zones[name].map(function(s) {return s.copy();});
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
constellation: map(state.constellation, id),
|
||||||
|
getColor: state.getColor,
|
||||||
|
missing: state.missing.copy(),
|
||||||
|
zones: zones
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCells(solvingState, value) {
|
||||||
|
return function(cellSet) {
|
||||||
|
for(var i = 0; i < zoneNames.length; i++) {
|
||||||
|
for(var j = 0; j < size; j++) {
|
||||||
|
f(solvingState.zones[field][j], cellSet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var field = zoneNames[i];
|
||||||
|
var zone = solvingState.zones[field][j];
|
||||||
|
if(zone.size() > 0) {
|
||||||
|
var diff =
|
||||||
|
});
|
||||||
|
solvingState.colorZones
|
||||||
|
.concat(solvingState.rows)
|
||||||
|
.concat(solvingState.columns)
|
||||||
|
.concat(solvingState.missing)
|
||||||
|
.forEach(function(cellSet) {cellSet.remove(cell);});
|
||||||
|
solvingState.missing
|
||||||
|
set(solvingState.constellation, cell, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function f(zone, cellSet) {
|
||||||
|
if(zone.size() > 0) {
|
||||||
|
var diff = zone.difference(cellSet);
|
||||||
|
if(diff.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue