(function() {
var COLS, DIGITS, ROWS, assign, c, copy, cross, cs, display, eliminate, grid_values, nine_squares, ns, parse_grid, peers, puzzle, r, rs, s, search, squares, u, uniq_and_remove, unitlist, units, _i, _j, _k, _l, _len, _len2, _len3, _len4, _len5, _len6, _m, _n, _ref, _ref2;
var __hasProp = Object.prototype.hasOwnProperty, __indexOf = Array.prototype.indexOf || function(item) {
for (var i = 0, l = this.length; i < l; i++) {
if (this[i] === item) return i;
}
return -1;
};
ROWS = "ABCDEFGHI";
COLS = "123456789";
DIGITS = COLS;
cross = function(A, B) {
var a, b, results, _i, _j, _len, _len2;
results = [];
for (_i = 0, _len = A.length; _i < _len; _i++) {
a = A[_i];
for (_j = 0, _len2 = B.length; _j < _len2; _j++) {
b = B[_j];
results.push(a + b);
}
}
return results;
};
copy = function(obj) {
var cl, k, v;
cl = {};
for (k in obj) {
if (!__hasProp.call(obj, k)) continue;
v = obj[k];
cl[k] = v;
}
return cl;
};
uniq_and_remove = function(duparr, ele) {
var arr, hash, key, sq, value, _i, _len;
hash = {};
for (_i = 0, _len = duparr.length; _i < _len; _i++) {
sq = duparr[_i];
hash[sq] = 0;
}
arr = [];
for (key in hash) {
if (!__hasProp.call(hash, key)) continue;
value = hash[key];
if (key !== ele) {
arr.push(key);
}
}
return arr;
};
squares = cross(ROWS, COLS);
nine_squares = [];
_ref = ['ABC', 'DEF', 'GHI'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
rs = _ref[_i];
_ref2 = ['123', '456', '789'];
for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
cs = _ref2[_j];
nine_squares.push(cross(rs, cs));
}
}
unitlist = ((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = COLS.length; _i < _len; _i++) {
c = COLS[_i];
_results.push(cross(ROWS, c));
}
return _results;
})()).concat((function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = ROWS.length; _i < _len; _i++) {
r = ROWS[_i];
_results.push(cross(r, COLS));
}
return _results;
})()).concat(nine_squares);
units = {};
for (_k = 0, _len3 = squares.length; _k < _len3; _k++) {
s = squares[_k];
units[s] = [];
for (_l = 0, _len4 = unitlist.length; _l < _len4; _l++) {
u = unitlist[_l];
if (__indexOf.call(u, s) >= 0) {
units[s].push(u);
}
}
}
peers = {};
for (_m = 0, _len5 = squares.length; _m < _len5; _m++) {
s = squares[_m];
peers[s] = [];
peers[s] = peers[s].concat(cross(ROWS, s[1])).concat(cross(s[0], COLS));
for (_n = 0, _len6 = nine_squares.length; _n < _len6; _n++) {
ns = nine_squares[_n];
if (__indexOf.call(ns, s) >= 0) {
peers[s] = peers[s].concat(ns);
}
}
peers[s] = uniq_and_remove(peers[s], s);
}
parse_grid = function(grid) {
var d, s, values, _i, _len, _ref;
values = {};
for (_i = 0, _len = squares.length; _i < _len; _i++) {
s = squares[_i];
values[s] = DIGITS;
}
_ref = grid_values(grid);
for (s in _ref) {
if (!__hasProp.call(_ref, s)) continue;
d = _ref[s];
if (__indexOf.call(DIGITS, d) >= 0 && !assign(values, s, d)) {
return False;
}
}
return values;
};
grid_values = function(sgrid) {
var grid, i, _ref, _ref2;
grid = {};
for (i = 0, _ref = sgrid.length; (0 <= _ref ? i < _ref : i > _ref); (0 <= _ref ? i += 1 : i -= 1)) {
grid[squares[i]] = (_ref2 = sgrid[i], __indexOf.call(DIGITS, _ref2) >= 0) ? sgrid[i] : ".";
}
return grid;
};
assign = function(values, s, d) {
var d2, other_values, _i, _len;
other_values = values[s].replace(d, '');
for (_i = 0, _len = other_values.length; _i < _len; _i++) {
d2 = other_values[_i];
if (!eliminate(values, s, d2)) {
return false;
}
}
return values;
};
eliminate = function(values, s, d) {
var d2, dplaces, s, s2, u, _i, _j, _len, _len2, _ref;
if (!(values[s].indexOf(d) >= 0)) {
return values;
}
values[s] = values[s].replace(d, '');
if (values[s].length === 0) {
return false;
} else if (values[s].length === 1) {
d2 = values[s];
_ref = peers[s];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
s2 = _ref[_i];
if (!eliminate(values, s2, d2)) {
return false;
}
}
}
for (_j = 0, _len2 = units.length; _j < _len2; _j++) {
u = units[_j];
dplaces = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = u.length; _i < _len; _i++) {
s = u[_i];
if (__indexOf.call(values[s], d) >= 0) {
_results.push(s);
}
}
return _results;
})();
if (dplaces.length === 0) {
return values;
}
if (dplaces.length === 1) {
if (!assign(values, dplaces[0], d)) {
return false;
}
}
}
return values;
};
display = function(values) {
var c, line, r, row, _i, _j, _len, _len2;
console.log(" " + COLS.replace(/(.)/g, "$1 "));
line = " |------+-----+-----|";
console.log(line);
for (_i = 0, _len = ROWS.length; _i < _len; _i++) {
r = ROWS[_i];
if (__indexOf.call("DG", r) >= 0) {
console.log(line);
}
row = r + " | ";
for (_j = 0, _len2 = COLS.length; _j < _len2; _j++) {
c = COLS[_j];
row = row.concat(values[r + c]);
row = row.concat(__indexOf.call("369", c) >= 0 ? "|" : " ");
}
console.log(row);
}
return console.log(line);
};
search = function(values) {
var d, key, max, min, sq, value, _i, _len, _ref;
if (!values) {
return false;
}
min = {
pos: -1,
length: 10
};
max = {
pos: -1,
length: 1
};
for (key in values) {
if (!__hasProp.call(values, key)) continue;
value = values[key];
if (value.length > max.length) {
max.length = value.length;
max.pos = key;
}
}
if (max.length === 1) {
return values;
}
for (key in values) {
if (!__hasProp.call(values, key)) continue;
value = values[key];
if (value.length < min.length && value.length > 1) {
min.length = value.length;
min.pos = key;
}
}
sq = squares[min.pos];
_ref = values[sq];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
d = _ref[_i];
if (!search(assign(copy(values), sq, values[sq][d]))) {
return true;
}
}
return false;
};
puzzle = '003020600900305001001806400008102900700000008006708200002609500800203009005010300';
display(search(parse_grid(puzzle)));
}).call(this);