From fb0c655089134ab66c1e4298bd35a4b72c32b10c Mon Sep 17 00:00:00 2001 From: Tissevert Date: Sun, 2 Oct 2022 22:17:27 +0200 Subject: [PATCH] [WIP, BROKEN] attempt to factorize zone handling to provide tooling to detect contradictions in hypothesis solver (zones becoming empty which shouldn't) --- js/Set.js | 1 + js/Solver.js | 10 +----- js/Solver/SingleCell.js | 11 +++---- js/Solver/State.js | 73 ++++++++++++++++++++++++++++++++--------- 4 files changed, 64 insertions(+), 31 deletions(-) diff --git a/js/Set.js b/js/Set.js index 2a30e9d..64a529c 100644 --- a/js/Set.js +++ b/js/Set.js @@ -21,6 +21,7 @@ function make(type) { Set.prototype.remove = function(e) { delete 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.copy = function() { return new Set(this.toList()); }; Set.prototype.toList = function() { var result = []; diff --git a/js/Solver.js b/js/Solver.js index 667ab49..2520121 100644 --- a/js/Solver.js +++ b/js/Solver.js @@ -39,16 +39,8 @@ function applyStep(solvingState) { console.log(step); ['empty', 'star'].forEach(function(attribute) { if(step[attribute] != undefined) { - step[attribute].iter(function(cell) { - set(solvingState.constellation, cell, attribute == 'star'); - forget(solvingState, cell); - }); + step[attribute].iter(State.setCell(solvingState, attribute == 'star')); } }); }; } - -function forget(solvingState, cell) { - State.getCellSets(solvingState).concat(solvingState.missing) - .forEach(function(cellSet) {cellSet.remove(cell);}); -} diff --git a/js/Solver/SingleCell.js b/js/Solver/SingleCell.js index 12fa09e..ddb4e4c 100644 --- a/js/Solver/SingleCell.js +++ b/js/Solver/SingleCell.js @@ -1,17 +1,16 @@ import * as CellSet from Geometry.CellSet; -import getCellSets from Solver.State; import * as Strategy from Solver.Strategy; import {diagonal, getColumn, getRow, plus} from Geometry.Vector; return { - find: find + find: find, + perimeter: perimeter }; function find(solvingState) { - var cellSets = getCellSets(solvingState); return Strategy.map( 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 { reason: 'singleCell', - empty: toEmpty(cell).intersection(missing), + empty: perimeter(cell).intersection(missing), star: new CellSet.CellSet(cell) }; }; } -function toEmpty(cell) { +function perimeter(cell) { var union = CellSet.union([ CellSet.rectangle(plus(cell, diagonal(-1)), diagonal(3)), CellSet.row(getRow(cell)), diff --git a/js/Solver/State.js b/js/Solver/State.js index 0dd641e..67f1515 100644 --- a/js/Solver/State.js +++ b/js/Solver/State.js @@ -1,11 +1,15 @@ +import id from UnitJS.Fun; 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 * as CellSet from Geometry.CellSet; +var zoneNames = ['colors', 'rows', 'columns']; + return { - getCellSets: getCellSets, - start: start + setCell: setCell, + start: start, + fork: fork }; function start(coloring) { @@ -14,25 +18,62 @@ function start(coloring) { constellation: square(size), getColor: asAFunction(coloring), missing: CellSet.rectangle(zero(), diagonal(size)), - colorZones: getZones(coloring), - rows: empty.map(function(_, i) {return CellSet.row(i);}), - columns: empty.map(function(_, i) {return CellSet.column(i);}) + zones: { + colors: getColors(coloring), + rows: empty.map(function(_, i) {return CellSet.row(i);}), + columns: empty.map(function(_, i) {return CellSet.column(i);}) + } }; } -function getZones(grid) { - var zones = Array.from({length: size}); +function getColors(grid) { + var colors = Array.from({length: size}); iter(grid, function(color, cell) { - if(zones[color] == undefined) { - zones[color] = new CellSet.CellSet(); + if(colors[color] == undefined) { + colors[color] = new CellSet.CellSet(); } - zones[color].add(cell); + colors[color].add(cell); }); - return zones; + return colors; } -function getCellSets(solvingState) { - return solvingState.colorZones - .concat(solvingState.rows) - .concat(solvingState.columns); +function fork(state) { + var zones = {}; + zoneNames.forEach(function(name) { + 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. + } }