PHP计算数独

以前很喜欢玩数独游戏,最近有空突然想到何不用php写个程序来计算数独

琢磨了一下, 大致思路是 横纵9个方格 放9个数字,每个数字在其横纵范围只出现一次.

php 里可以用二维数组表示 例如

array(

 array(6 , 7 , 9 , 4 , 5 , 8 , 2 , 1 , 3)
  array(2 , 3 , 5 , 9 , 1 , 4 , 7 , 6 , 8)
  array(1 , 2 , 4 , 8 , 9 , 3 , 6 , 5 , 7)
  array(9 , 1 , 3 , 7 , 8 , 2 ,  5 , 4 , 6)
  array(8 , 9 , 2 , 6 , 7, 1 , 4 , 3 , 5)
  array(3 , 4 , 6 , 1 , 2 , 5 , 8 , 7 , 9)
  array(7 , 8 , 1 , 5 , 6 , 9 , 3 , 2 , 4)
  array(4 , 5 , 7 , 2 , 3 , 6 , 9 , 8 , 1)
  array(5 , 6 , 8 , 3 , 4 , 7 , 1 , 9 , 2)

);

 上面的二维数组就是一个数独的解.而数独游戏就是挖去里面的一些数字,然后靠推理计算得出这个解.

那么程序里可以把这些被挖去的数字设置为0 

例如:

array(

 array(6 , 7 , 0 , 4 , 5 , 0 , 2 , 1 , 3)
  array(2 , 0 , 5 , 0, 1 , 4 , 7 , 6 , 8)
  array(1 , 0 , 0 , 0 , 9 , 3 , 6 , 5 , 7)
  array(9 , 1 , 3 , 7 , 8 , 0 ,  5 , 4 ,0)
  array(8 , 9 , 0 , 6 , 7, 1 , 4 , 3 , 0)
  array(0 , 4 , 0 , 1 , 2 , 0 , 8 , 7 , 0)
  array(7 , 0 , 1 , 5 , 0 , 9 , 3 , 2 , 4)
  array(0 , 5 , 7 , 2 , 3 , 6 , 9 , 8 , 1)
  array(5 , 6 , 8 , 0, 0 , 0 , 1 , 9 , 2)

);

这就是一个数独题. 现在就需要写个程序来求出解.

初步代码就很简单了.如下

class shudu{
	public $data;
	function shudu($data){
		$this->data = array();
		foreach($data as $k=>$v){
			foreach($v as $ka=>$va){
				$this->data[$k][$ka] = $va;
				$this->row[$k][]=$va;
				$this->col[$ka][]=$va;
			}
		}

	}
	function cal(){
		for($i=0;$i<9;$i++){
			for($j=0;$j<9;$j++){
				if($this->data[$i][$j] == 0) {
					for($n=1;$n<10;$n++){
						if(in_array($n,$this->row[$i]) || in_array($n,$this->col[$j])) continue;
						$this->data[$i][$j] = $n;
						$this->row[$i][]=$n;
						$this->col[$j][]=$n;
						$s = new shudu($this->data);
						$s->cal();
					}
					if($this->data[$i][$j] == 0){
						return false;
					}
				}
			}
		}
		$this->out();
	}
	function out(){
		for($i = 0; $i < 9; $i++){
			for($j = 0; $j < 9; $j++){
				echo " ".$this->data[$i][$j]." ";
			}
			echo "\n";
		}
		die;
	}
}


$arr = array(
array(6,7,0,4,5,0,2,1,3),
array(2,0,5,0,1,4,7,6,8),
array(1,0,0,0,9,3,6,5,7),
array(9,1,3,7,8,0,5,4,0),
array(8,9,0,6,7,1,4,3,0),
array(0,4,0,1,2,0,8,7,0),
array(7,0,1,5,0,9,3,2,4),
array(0,5,7,2,3,6,9,8,1),
array(5,6,8,0,0,0,1,9,2),
);


$s=new shudu($arr);
$s->cal();

结果输出

 6  7  9  4  5  8  2  1  3
 2  3  5  9  1  4  7  6  8
 1  2  4  8  9  3  6  5  7
 9  1  3  7  8  2  5  4  6
 8  9  2  6  7  1  4  3  5
 3  4  6  1  2  5  8  7  9
 7  8  1  5  6  9  3  2  4
 4  5  7  2  3  6  9  8  1
 5  6  8  3  4  7  1  9  2

就得到答案了..

程序本身还可以优化一下.目前是一行一行扫描可以考虑用随机填空的模式或者根据当前已知出现最多的数字来一个个填或者缺少数字最少的行或者列开始扫描.计算速度就会快很多了.

算法有待完善.不过这个程序应付一般的数独题目应该是足够了.

更高级的应用还有采用多线程和分布式计算.多行多列同时扫描, 那样计算速度还会以数量级的形式上升.当然这就有点大炮打文字的感觉了.

转载于:https://my.oschina.net/jiuxiaoyao/blog/753022

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值