数独计算机在线,js数独计算器

//clear all the input

function clc() {

for (let i = 0; i < 81; i++) {

document.getElementsByTagName("input")[i].value = "";

document.getElementsByTagName("input")[i].style.color = '#00d3ff';

}

alert("已清理所有单元格");

}

//press "show answer" button and show answer then

function get_answer() {

let bool = check_input();

if (bool) {

let grid = readAPuzzle();

if (!isValidGrid(grid)) {

alert("输入无效,请重试!(可能误输重复数字)");

} else {

if (search(grid)) {

output_ans();

} else {

alert("找不到解决方案!(无解)");

}

}

}

}

//check if the input are valid

function check_input() {

let arr = new Array();

for (let i = 0; i < 81; i++) {

arr[i] = Number(document.getElementsByTagName("input")[i].value);

if (isNaN(arr[i])) {

alert('输入应该是1到9之间的任何数字!');

return false

}

}

if (arr.every(function isZero(x) {

return x == 0

})) {

alert('没有输入!');

return false

}

return true

}

//read a puzzle from the web page

function readAPuzzle() {

let arr = new Array();

for (let i = 0; i < 81; i++) {

arr[i] = Number(document.getElementsByTagName("input")[i].value);

}

let grid = new Array();

for (let i = 0; i < 9; i++) {

grid[i] = new Array();

for (let j = 0; j < 9; j++) {

grid[i][j] = 0;

}

}

for (let i = 0; i < 81; i++) {

grid[Math.floor(i / 9)][i % 9] = arr[i];

}

return grid

}

//Obtain a list of free cells from the puzzle

function getFreeCellList(grid) {

let freeCellList = new Array();

let index = 0

for (let i = 0; i < 9; i++) {

for (let j = 0; j < 9; j++) {

if (grid[i][j] == 0) {

freeCellList[index] = new Array(i, j);

index++;

}

}

}

return freeCellList

}

//Check whether grid[i][j] is valid in the grid

function isValid(i, j, grid) {

//Check whether grid[i][j] is valid at the i's row

for (var column = 0; column < 9; column++) {

if ((column != j) && (grid[i][column] == grid[i][j])) {

return false

}

}

//Check whether grid[i][j] is valid at the j's column

for (var row = 0; row < 9; row++) {

if ((row != i) && (grid[row][j] == grid[i][j])) {

return false

}

}

//Check whether grid[i][j] is valid at the 3-by-3 box

for (var row = Math.floor(i / 3) * 3; row < Math.floor(i / 3) * 3 + 3; row++) {

for (var col = Math.floor(j / 3) * 3; col < Math.floor(j / 3) * 3 + 3; col++) {

if ((row != i) && (col != j) && (grid[row][col] == grid[i][j])) {

return false

}

}

}

return true //The current value at grid[i][j] is valid

}

//Check whether the fixed cells are valid in the grid

function isValidGrid(grid) {

for (var i = 0; i < 9; i++) {

for (var j = 0; j < 9; j++) {

if ((grid[i][j] < 0) || (grid[i][j] > 9) || ((grid[i][j] != 0) && (!isValid(i, j, grid)))) {

return false

}

}

}

return true

}

//Search for a solution

function search(grid) {

var freeCellList = getFreeCellList(grid);

var numberOfFreeCells = freeCellList.length;

if (numberOfFreeCells == 0) {

return true

}

var k = 0; //Start from the first free cell

while (true) {

var i = freeCellList[k][0];

var j = freeCellList[k][1];

if (grid[i][j] == 0) {

grid[i][j] = 1;

}

if (isValid(i, j, grid)) {

if (k + 1 == numberOfFreeCells) {

//no more free cells

return true //A solution is found

} else {

//Move to the next free cell

k++;

}

} else {

if (grid[i][j] < 9) {

//Fill the free cell with the next possible value

grid[i][j]++;

} else {

//grid[i][j] is 9,backtrack

while (grid[i][j] == 9) {

if (k == 0) {

return false //No possible value

}

grid[i][j] = 0; //Reset to free cell

k--; //Backtrack to the preceding free cell

i = freeCellList[k][0];

j = freeCellList[k][1];

}

//Fill the free cell with the next possible value

//search continues from this free cell at k

grid[i][j]++;

}

}

}

return true //A solution is found

}

//output the answer on the web page

function output_ans() {

var grid = readAPuzzle();

var grid_original = readAPuzzle();

if (search(grid)) {

for (var i = 0; i < 81; i++) {

if (grid[Math.floor(i / 9)][i % 9] != grid_original[Math.floor(i / 9)][i % 9]) {

document.getElementsByTagName("input")[i].value = grid[Math.floor(i / 9)][i % 9];

document.getElementsByTagName("input")[i].style.color = '#2DFF97';

}

}

}

}

数独算法说明:用三个二维数组记录数独每个点的状态,SD(i, j)显示数值,也是真实数值(1到9)。ST(i, j)状态,1可由用户输入,2是题目给定的,不能改。SY(i, j)这符串,记录每个点中可能的值。 1、在进行自动计算时,只计算ST(i, j)为1的点,首先将所有状态为1的点的SY(i, j)值全部设为"123456789",SD(i, j)值全部设为0 2、逐点扫描,找到一个点,然后将该点所在的行、列、区域中已存在的SD(x, y)值从SY(i, j)中删除,因为数独规则是一个数值,在行、列、区域都不重复。 3、经第二步处理后,SY(i, j)为空,说明题目错误,SY(i, j)值为一位数字,就说明该点的值是唯一的,可以确定了。 4、剩余的SY(i, j)值最少也是二个数字的,或更多位数。随机从这些两位数的SY(i, j)中选取一个点。取其中的一位确定为该点的值后,重复第2步。如果错误遇错,则重复执行第4步。直到所有点都被确定。 注意:第2步是需要多次重复执行的,所有可用递归函数完成。如果执行结果出现错误(某数出现重复,或某点无值),需要对该过程所执行的所有操作进行回退。 第4步也是需要重复执行的。本和序用Goto跳转方式实现多次执行。 简单的数独,要么所有的点都具有独一值,第1步执行完成后,就已全部完成。或者具有多个解,随意猜测一个二位数的SY(i, j)的值都能成功。 难的数独,是可唯一确定的点很少,大部分点都有两种或多种可能的值,但最终正确答案只有一种或很少种解。 软件在自动计算过程中,具有很大的偶然性,对于骨灰级的数独题目在计算过程中,时间短的可能不到1秒就能完成,长的可能要几分钟,需要将各种可能性都测试一遍才有结果。 只要题目正确,多计算几次就能得到答案。 程序只处理有两种可能值的情况,对只存在三种可能值的情况未进一步处理,该情况非常极端了。 软件中包含网上下载的200个数独题目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值