Added deduction logic checks (if there's a value only in one row/col in a square, it can't be in the rest of the row/col)
This commit is contained in:
@ -75,7 +75,7 @@
|
||||
return;
|
||||
}
|
||||
dim2 = cells[0].boardObj.dim2;
|
||||
console.group('twoValPlaces: (%o) %o', dim2, cells);
|
||||
console.groupCollapsed('twoValPlaces: (%o) %o', dim2, cells);
|
||||
for (i = _i = 0, _ref = dim2 - 1; _i < _ref; i = _i += 1) {
|
||||
for (j = _j = _ref1 = i + 1; _j < dim2; j = _j += 1) {
|
||||
n = 0;
|
||||
@ -110,6 +110,37 @@
|
||||
return true;
|
||||
};
|
||||
|
||||
SudokuChecks.rowMatch = function(blockSubject, blockRest, lineRest) {
|
||||
var i, isInRest, isInSubject, j, p, _i, _ref;
|
||||
if (!blockSubject[0] || !blockRest[0] || !lineRest[0]) {
|
||||
return;
|
||||
}
|
||||
console.groupCollapsed('rowMatch: %o, %o, %o', blockSubject, blockRest, lineRest);
|
||||
for (i = _i = 0, _ref = blockSubject[0].boardObj.dim2; _i < _ref; i = _i += 1) {
|
||||
p = 1 << i;
|
||||
isInSubject = false;
|
||||
isInRest = false;
|
||||
for (j in blockSubject) {
|
||||
if (blockSubject[j].getValue() === '.' && (p & blockSubject[j].getMask())) {
|
||||
isInSubject = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (j in blockRest) {
|
||||
if (blockRest[j].getValue() === '.' && (p & blockRest[j].getMask())) {
|
||||
isInRest = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isInSubject && !isInRest) {
|
||||
for (j in lineRest) {
|
||||
lineRest[j].setMask(lineRest[j].getMask() & ~p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return console.groupEnd();
|
||||
};
|
||||
|
||||
return SudokuChecks;
|
||||
|
||||
})();
|
||||
|
@ -1,5 +1,7 @@
|
||||
// Generated by CoffeeScript 1.6.3
|
||||
(function() {
|
||||
var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
this.SudokuSolver = (function() {
|
||||
function SudokuSolver() {}
|
||||
|
||||
@ -50,6 +52,96 @@
|
||||
return result;
|
||||
};
|
||||
|
||||
SudokuSolver.getSquareColCells = function(board, squareid, squarecol) {
|
||||
var cx, i, rb, result, _i, _ref;
|
||||
result = [];
|
||||
rb = Math.floor(squareid / board.dim) * board.dim;
|
||||
cx = squareid % board.dim * board.dim + squarecol;
|
||||
for (i = _i = 0, _ref = board.dim; _i < _ref; i = _i += 1) {
|
||||
result.push(board.cellAt(cx, rb + i));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
SudokuSolver.getSquareNonColCells = function(board, squareid, squarecol) {
|
||||
var cx, i, j, rb, result, _i, _j, _ref, _ref1;
|
||||
result = [];
|
||||
rb = Math.floor(squareid / board.dim) * board.dim;
|
||||
cx = squareid % board.dim * board.dim;
|
||||
for (i = _i = 0, _ref = board.dim; _i < _ref; i = _i += 1) {
|
||||
if (i === squarecol) {
|
||||
continue;
|
||||
}
|
||||
for (j = _j = 0, _ref1 = board.dim; _j < _ref1; j = _j += 1) {
|
||||
result.push(board.cellAt(cx + i, rb + j));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
SudokuSolver.getNonSquareColCells = function(board, squareid, squarecol) {
|
||||
var cx, i, rb, result, _i, _j, _ref, _ref1, _results;
|
||||
result = [];
|
||||
rb = Math.floor(squareid / board.dim) * board.dim;
|
||||
cx = squareid % board.dim * board.dim + squarecol;
|
||||
for (i = _i = 0, _ref = board.dim2; _i < _ref; i = _i += 1) {
|
||||
if (__indexOf.call((function() {
|
||||
_results = [];
|
||||
for (var _j = rb, _ref1 = rb + board.dim; rb <= _ref1 ? _j < _ref1 : _j > _ref1; rb <= _ref1 ? _j++ : _j--){ _results.push(_j); }
|
||||
return _results;
|
||||
}).apply(this), i) >= 0) {
|
||||
continue;
|
||||
}
|
||||
result.push(board.cellAt(cx, i));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
SudokuSolver.getSquareRowCells = function(board, squareid, squarerow) {
|
||||
var cb, i, result, ry, _i, _ref;
|
||||
result = [];
|
||||
cb = squareid % board.dim * board.dim;
|
||||
ry = Math.floor(squareid / board.dim) * board.dim + squarerow;
|
||||
for (i = _i = 0, _ref = board.dim; _i < _ref; i = _i += 1) {
|
||||
result.push(board.cellAt(cb + i, ry));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
SudokuSolver.getSquareNonRowCells = function(board, squareid, squarerow) {
|
||||
var cb, i, j, result, ry, _i, _j, _ref, _ref1;
|
||||
result = [];
|
||||
cb = squareid % board.dim * board.dim;
|
||||
ry = Math.floor(squareid / board.dim) * board.dim;
|
||||
for (i = _i = 0, _ref = board.dim; _i < _ref; i = _i += 1) {
|
||||
if (i === squarerow) {
|
||||
continue;
|
||||
}
|
||||
for (j = _j = 0, _ref1 = board.dim; _j < _ref1; j = _j += 1) {
|
||||
result.push(board.cellAt(cb + j, ry + i));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
SudokuSolver.getNonSquareRowCells = function(board, squareid, squarerow) {
|
||||
var cb, i, result, ry, _i, _j, _ref, _ref1, _results;
|
||||
result = [];
|
||||
cb = squareid % board.dim * board.dim;
|
||||
ry = Math.floor(squareid / board.dim) * board.dim + squarerow;
|
||||
for (i = _i = 0, _ref = board.dim2; _i < _ref; i = _i += 1) {
|
||||
if (__indexOf.call((function() {
|
||||
_results = [];
|
||||
for (var _j = cb, _ref1 = cb + board.dim; cb <= _ref1 ? _j < _ref1 : _j > _ref1; cb <= _ref1 ? _j++ : _j--){ _results.push(_j); }
|
||||
return _results;
|
||||
}).apply(this), i) >= 0) {
|
||||
continue;
|
||||
}
|
||||
result.push(board.cellAt(i, ry));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
SudokuSolver.runAllRows = function(board, func) {
|
||||
var i, rowcells, _i, _ref, _results;
|
||||
_results = [];
|
||||
@ -95,6 +187,50 @@
|
||||
return SudokuChecks[func](diag2);
|
||||
};
|
||||
|
||||
SudokuSolver.runSpecialColumns = function(board, func) {
|
||||
var blockCol, blockRest, c, colRest, s, _i, _ref, _results;
|
||||
blockCol = [];
|
||||
blockRest = [];
|
||||
colRest = [];
|
||||
_results = [];
|
||||
for (s = _i = 0, _ref = board.dim2; _i < _ref; s = _i += 1) {
|
||||
_results.push((function() {
|
||||
var _j, _ref1, _results1;
|
||||
_results1 = [];
|
||||
for (c = _j = 0, _ref1 = board.dim; _j < _ref1; c = _j += 1) {
|
||||
blockCol = this.getSquareColCells(board, s, c);
|
||||
blockRest = this.getSquareNonColCells(board, s, c);
|
||||
colRest = this.getNonSquareColCells(board, s, c);
|
||||
_results1.push(SudokuChecks[func](blockCol, blockRest, colRest));
|
||||
}
|
||||
return _results1;
|
||||
}).call(this));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
|
||||
SudokuSolver.runSpecialRows = function(board, func) {
|
||||
var blockRest, blockRow, r, rowRest, s, _i, _ref, _results;
|
||||
blockRow = [];
|
||||
blockRest = [];
|
||||
rowRest = [];
|
||||
_results = [];
|
||||
for (s = _i = 0, _ref = board.dim2; _i < _ref; s = _i += 1) {
|
||||
_results.push((function() {
|
||||
var _j, _ref1, _results1;
|
||||
_results1 = [];
|
||||
for (r = _j = 0, _ref1 = board.dim; _j < _ref1; r = _j += 1) {
|
||||
blockRow = this.getSquareRowCells(board, s, r);
|
||||
blockRest = this.getSquareNonRowCells(board, s, r);
|
||||
rowRest = this.getNonSquareRowCells(board, s, r);
|
||||
_results1.push(SudokuChecks[func](blockRow, blockRest, rowRest));
|
||||
}
|
||||
return _results1;
|
||||
}).call(this));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
|
||||
SudokuSolver.oneUnknownAll = function(board) {
|
||||
var c, cells, r, _i, _j, _ref, _ref1;
|
||||
cells = [];
|
||||
@ -138,6 +274,14 @@
|
||||
return this.runBothDiags(board, 'twoValPlaces');
|
||||
};
|
||||
|
||||
SudokuSolver.oneColumnForValue = function(board) {
|
||||
return this.runSpecialColumns(board, 'rowMatch');
|
||||
};
|
||||
|
||||
SudokuSolver.oneRowForValue = function(board) {
|
||||
return this.runSpecialRows(board, 'rowMatch');
|
||||
};
|
||||
|
||||
SudokuSolver.solveBoard = function(board) {
|
||||
var body, c, checks, description, i;
|
||||
checks = {
|
||||
@ -150,7 +294,9 @@
|
||||
'twoValPlacesRow': 'Only two possible places for pair in row.',
|
||||
'twoValPlacesColumn': 'Only two possible places for pair in column.',
|
||||
'twoValPlacesDiag': 'Only two possible places for pair in diagonale.',
|
||||
'oneUnknownAll': 'Only one possible value left.'
|
||||
'oneUnknownAll': 'Only one possible value left.',
|
||||
'oneColumnForValue': 'Only one possible column for value.',
|
||||
'oneRowForValue': 'Only one possible row for value.'
|
||||
};
|
||||
i = 1;
|
||||
while (true) {
|
||||
|
Reference in New Issue
Block a user