Skip to content

Instantly share code, notes, and snippets.

@Xmerr
Created January 4, 2018 15:15
Show Gist options
  • Save Xmerr/9ae10593b1889a8780ec191ad2242d28 to your computer and use it in GitHub Desktop.
Save Xmerr/9ae10593b1889a8780ec191ad2242d28 to your computer and use it in GitHub Desktop.
Sodoku Solver - created for websudoku.com but can altered to work for any sodoku website.
(function(){
/**
* A single sodoku cell
*/
var cell = function(col, row) {
this.col = col;
this.row = row;
this.block = (Math.floor(col / 3) * 10) + Math.floor(row / 3);
this.id = "f" + col + "" + row;
this.value = document.getElementById(this.id).value;
this.value = this.value.indexOf(',') !== -1 ? "" : this.value;
this.numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
};
cells = [];
/**
* Sets the cells value
*/
cell.prototype.setValue = function(val) {
var dom = document.getElementById(this.id);
var valChange = dom.value !== val;
dom.value = val;
dom.onkeyup();
return valChange;
};
/**
* Returns all cells on this row
*/
cell.prototype.cellRow = function() {
var thatRow = this.row;
return cells.filter(function(ob) {
return ob.row === thatRow;
});
};
/**
* Returns all cells on this column
*/
cell.prototype.cellCol = function() {
var thatCol = this.col;
return cells.filter(function(ob) {
return ob.col === thatCol;
});
};
/**
* Returns all cells in this block
*/
cell.prototype.cellBlock = function() {
var thatBlock = this.block;
return cells.filter(function(ob) {
return ob.block === thatBlock;
});
};
/**
* Guesses the cells value based on possible numbers.
* If there is only one possible number, that must be the answer
*/
cell.prototype.cellGuess = function() {
var myCells = [...this.cellRow(), ...this.cellCol(), ...this.cellBlock()];
for(var i = myCells.length - 1; i >= 0; i--)
this.numbers = checkCell(myCells[i], this.numbers);
if(this.numbers.length === 1) {
this.setValue(this.numbers.toString());
this.value = this.numbers.toString();
changed = true;
}
else if(this.setValue(this.numbers.join(',')))
changed = true;
};
/**
* Guesses the cells value based on possible numbers.
* If this cell is the only one that can hold this number, that number must belong to this cell
*/
cell.prototype.numberGuess = function () {
var myCells = [this.cellRow(), this.cellCol(), this.cellBlock()];
for(var k = myCells.length - 1; k >= 0; k--) {
for(var j = this.numbers.length - 1; j >= 0; j--) {
var found = false;
for(var i = myCells[k].length - 1; i >= 0; i--) {
if(myCells[k][i].id !== this.id && checkNumber(myCells[k][i], this.numbers[j])) {
found = true;
break;
}
}
if(!found){
this.setValue(this.numbers[j]);
this.value = this.numbers[j];
changed = true;
return;
}
}
}
};
/**
* Guesses the cells value based on possible numbers.
* If there is only one possible number, that must be the answer
*/
var checkCell = function(c, numbers) {
if(c.value)
return numbers.filter(function(num) {
return num !== parseInt(c.value);
});
return numbers;
};
/**
* Guesses the cells value based on possible numbers.
* If this cell is the only one that can hold this number, that number must belong to this cell
*/
var checkNumber = function(c, number) {
if(c.value)
return c.value == number;
return c.numbers.indexOf(number) !== -1;
};
/**
* Gets all the cells in an array
*/
for(var i = 0; i <= 8; i++)
for(var j = 0; j <= 8; j++)
cells.push(new cell(i, j));
var changed = false;
/**
* Attempts to solve the puzzle
*/
var solve = function () {
cellGuess();
var count = 0;
while(changed && count < 100) {
count++;
changed = false;
cellGuess();
numberGuess();
}
if(changed) {
console.log("ERROR 1");
return;
}
for(var i = cells.length - 1; i >= 0; i--) {
if(!cells[i].value) {
console.log("could not solve");
return;
}
}
console.log('solved in ' + count + ' iterations');
};
/**
* Guesses the cells value based on possible numbers.
* If there is only one possible number, that must be the answer
*/
var cellGuess = function () {
for(var i = cells.length - 1; i >= 0; i--) {
if(cells[i].value)
continue;
cells[i].cellGuess();
}
};
/**
* Guesses the cells value based on possible numbers.
* If this cell is the only one that can hold this number, that number must belong to this cell
*/
var numberGuess = function () {
for(var i = cells.length - 1; i >= 0; i--) {
if(cells[i].value)
continue;
cells[i].numberGuess();
}
};
solve();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment