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原生的方法在效率上及编程可读性上有更多的优势。

posted @ 2013-05-31 19:11  KallMeNeo  阅读(...)  评论(...编辑  收藏