js 解数独程序
今天来贡献一个代码,用js写的解数独程序
suduku_solve = function() { console.time("sudoku_solve"); // build structure var cells = Array(81), rows = Array(9), cols = Array(9), grids = Array(9); for ( var i = 0; i < 9; i++) { rows[i] = []; cols[i] = []; grids[i] = []; } for ( var row = 0; row < 9; row++) { for ( var col = 0; col < 9; col++) { var grid = row - row % 3 + col / 3 << 0; var cell = cells[row * 9 + col] = { row : row, col : col, grid : grid, value : +arguments[row].charAt(col) }; rows[row].push(cell); cols[col].push(cell); grids[grid].push(cell); } } cells.forEach(function(cell) { var arr = cell.groups = [ cell ]; rows[cell.row].concat(cols[cell.col]).concat(grids[cell.grid]).forEach(function(obj) { if (arr.indexOf(obj) === -1) { arr.push(obj); } }); arr.shift(); }); var results = []; solve(0); function solve(n) { // console.log("solving depth " + n); if (n === 81) { // solved var result = cells.map(function(cell) { return cell.value; }); console.log(result); results.push(result); console.timeEnd("sudoku_solve"); return; } var cell = cells[n]; if (cell.value) { solve(n + 1); } else { for ( var i = 1; i <= 9; i++) { if (cell.groups.some(function(obj) { return obj.value === i; })) { continue; } cell.value = i; solve(n + 1); } cell.value = 0; } } console.log("found " + results.length + " results"); return results; };
调用方法是:
suduku_solve( "8 ", " 36 ", " 7 9 2 ", " 5 7 ", " 457 ", " 1 3 ", " 1 68", " 85 1 ", " 9 4 " );
基本思路
这段代码用了递归的方式,对81个格子进行遍历。对于许多数独程序来说,最复杂的地方在于找到相关联的20个格子(同行、同列、同块),而这段代码一开始就把这部工作一次性完成了,扫描了所有单元格相关的格子,即代码中的cell.groups。这样在接下来的遍历中,仅通过线性的遍历groups即可完成条件检查。用这个思路也可以完成星形等复杂的数独类型。
这里用到了几个数组的函数:forEach、map等。相对于使用循环进行遍历,使用Array原生的方法在效率上及编程可读性上有更多的优势。