php生成和解决数独

php生成数独和判断数独是否是合理的数独,并给出解决方案:

php 复制代码
<?php

namespace numbers;

require "SudokuGenerator.php";

class SudokuSolve
{
    /**
     * 解数独
     * @param String[][] $board
     * @return NULL
     */
    public function solveSudoku(&$board)
    {
        if (count($board) != 9 || count($board[0]) != 9) return false;
        //初始化
        $rows = $columns = $blocks = [];
        $nums = array_flip(range(1, 9));
        for ($i = 0; $i < 9; $i++) {
            $rows[$i] = $nums;
            $columns[$i] = $nums;
            $blocks[$i] = $nums;
        }
        //收集需要填数的位置
        $empty = [];
        for ($i = 0; $i < 9; $i++) {
            for ($j = 0; $j < 9; $j++) {
                if ($board[$i][$j] != '.') {
                    $num = $board[$i][$j];
                    $b = intval($i / 3) * 3 + intval($j / 3);
                    unset($rows[$i][$num], $columns[$j][$num], $blocks[$b][$num]);
                } else {
                    $empty[] = [$i, $j];
                }
            }
        }
        return $this->backtrack($board, $empty, $rows, $columns, $blocks);
    }

    private function backtrack(&$board, $empty, $rows, $columns, $blocks, $index = 0)
    {
        if ($index == count($empty)) {
            return true;
        }
        [$i, $j] = $empty[$index];
        $b = intval($i / 3) * 3 + intval($j / 3);
        $nums = array_intersect(array_keys($rows[$i]), array_keys($columns[$j]), array_keys($blocks[$b]));
        foreach ($nums as $num) {
            unset($rows[$i][$num], $columns[$j][$num], $blocks[$b][$num]);
            $board[$i][$j] = (int)$num;
            if ($this->backtrack($board, $empty, $rows, $columns, $blocks, $index + 1))
                return true;
            $rows[$i][$num] = $num;
            $columns[$j][$num] = $num;
            $blocks[$b][$num] = $num;
        }
        return false;
    }

    // 对前端传来的数独结果进行检测
    public function isValidSudoku($board)
    {
        $rows = array_fill(0, 9, array_fill(0, 9, false));
        $columns = array_fill(0, 9, array_fill(0, 9, false));
        $subBoxes = array_fill(0, 3, array_fill(0, 3, array_fill(0, 9, false)));
        foreach ($board as $i => $row) {
            foreach ($row as $j => $c) {
                if ($c !== 0) {
                    $index = ord($c) - ord('1');

                    if ($rows[$i][$index] || $columns[$j][$index] || $subBoxes[$i / 3][$j / 3][$index]) {
                        return false;
                    }

                    $rows[$i][$index] = true;
                    $columns[$j][$index] = true;
                    $subBoxes[$i / 3][$j / 3][$index] = true;
                }
            }
        }
        return true;
    }
}

$solution = new SudokuSolve();
$board =
    // [["5", "3", 0, 0, "7", 0, 0, 0, 0], ["6", 0, 0, "1", "9", "5", 0, 0, 0], [0, "9", "8", 0, 0, 0, 0, "6", 0], ["8", 0, 0, 0, "6", 0, 0, 0, "3"], ["4", 0, 0, "8", 0, "3", 0, 0, "1"], ["7", 0, 0, 0, "2", 0, 0, 0, "6"], [0, "6", 0, 0, 0, 0, "2", "8", 0], [0, 0, 0, "4", "1", "9", 0, 0, "5"], [0, 0, 0, 0, "8", 0, 0, "7", "9"]];
// $board = [[4, 7, 0, 3, 9, 1, 5, 6, 2], [0, 0, 0, 0, 5, 6, 4, 1, 7], [6, 1, 0, 4, 7, 2, 9, 8, 3], [0, 0, 6, 2, 0, 3, 1, 7, 0], [8, 2, 1, 7, 6, 0, 0, 9, 4], [3, 5, 7, 1, 4, 9, 0, 2, 0], [1, 9, 4, 5, 2, 0, 6, 3, 8], [7, 8, 0, 6, 1, 4, 2, 0, 9], [0, 6, 2, 9, 0, 0, 0, 4, 1]];
$sudokuGenerator = new SudokuGenerator();
$sudoku = $sudokuGenerator->generateSudoku();
$board = $sudokuGenerator->removeNumbers(60);  // 难度级别,可以调整,越大越难
var_dump(json_encode($board, 320));

$isValidSudoku = $solution->isValidSudoku($board);
if (!$isValidSudoku) {
    echo '数独不合法!';
    die();
}
echo '数独合法!解答如下:';
$solution->solveSudoku($board);

// 数独结果
var_dump(json_encode($board, 320));
相关推荐
我材不敲代码1 天前
Python实现打包贪吃蛇游戏
开发语言·python·游戏
身如柳絮随风扬1 天前
Java中的CAS机制详解
java·开发语言
韩立学长1 天前
【开题答辩实录分享】以《基于Python的大学超市仓储信息管理系统的设计与实现》为例进行选题答辩实录分享
开发语言·python
froginwe111 天前
Scala 循环
开发语言
m0_706653231 天前
C++编译期数组操作
开发语言·c++·算法
故事和你911 天前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
Bruk.Liu1 天前
(LangChain实战2):LangChain消息(message)的使用
开发语言·langchain
qq_423233901 天前
C++与Python混合编程实战
开发语言·c++·算法
m0_715575341 天前
分布式任务调度系统
开发语言·c++·算法
csbysj20201 天前
选择(Selectable)
开发语言