数独高级算法,直接复制到网页,即可结题

数独弄好了。可以尝试放数字。理论上可以遍历所有解。定义初始全为空,这个程序会一个一个放数字例如:

你说这个有解吗?我正在运算中已经几分钟了,还没结果。。先贴下HTML界面部分。竟然有解。。。

里面好像有0,这个结果不对。

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta name="renderer" content="webkit">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=540">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="applicable-device" content="pc">
</head>
<body  >
<!-- head,css -->
<style type="text/css">	
	html,body,ul,li div{margin: 0;padding:0;}
	.clearfix:after{content:"";display:block;clear:both;}
	.clearfix{zoom:1;}
	.box_bg  {width: 400px;height: 396px;background-color: #7f5a0f;margin: 0 auto;padding-top: 20px;padding-bottom: 20px;  }
	.box_bg ul {width: 380px;margin: 0 auto;border:2px solid #ab8d17;background-color: #fff;}
	.box_bg ul li {display: block;float: left;width: 40px;height: 40px;border:1px solid #d6c079;line-height: 40px;text-align: center;font-size:26px;color:#383838;font-weight: bold;}
	.box_bg ul li.border_right{border-right:2px solid #c19502;}
	.box_bg ul li.border_bottom{border-bottom:2px solid #c19502;}
	.box_bg .on{background-color: #ffe000;}
	.box_bg .red1{background-color: #d44b6a;}
	.box_bg .red2{background-color: #e40e3e;}
	.box_bg .red3{background-color: #f588a0;}
	#selectbox {    z-index: 1000;width: 115px;height: 152px;background-color: #deecfd;margin: 0 auto;     position: absolute; display: none;  }
	#selectbox ul {width: 112px;margin: 0 auto;border:2px solid #deecfd;}
	#selectbox ul li {display: block;float: left;width: 35px;height: 35px;border:1px solid #d6c079;line-height: 35px;text-align: center;font-size:20px;color:#383838;font-weight: bold;}
	#selectbox ul li.border_right{border-right:2px solid #c19502;}
	#selectbox ul li.border_bottom{border-bottom:2px solid #c19502;} 
	.maybebox { width: 39px;height: 38px;background-color: #deecfd;margin: 0 auto;     position: absolute; display: none;  }
 	.maybebox ul {width: 39px;margin: 0 auto; }
	.maybebox ul li {display: block;float: left;width: 13px;height: 13px; line-height: 15px;text-align: center;font-size:10px;color:#383838;font-weight: bold;}
	.maybebox ul li.border_right{border-right:2px solid #c19502;}
	.maybebox ul li.border_bottom{border-bottom:2px solid #c19502;} 
	.button {    z-index: 10;width: 484px;height: 35px;background-color: #deecfd;margin: 0 auto;     position: absolute;   }
	.button ul {width: 483px;margin: 0 auto;border:2px solid #deecfd;}
	.button ul li {display: block;float: left;width: 159px;height: 31px;border:1px solid #d6c079;line-height: 35px;text-align: center;font-size:15px;color:#383838;font-weight: bold;}
</style> 
<script type="text/javascript" src="/lib/jquery-3.4.1/jquery-3.4.1.min.js"></script>
  
<!-- body -->
<div id="shudubox" class="box_bg"></div>

<div id="selectbox" targetid="" >
	<ul>
		<li>1</li>
		<li>2</li>
		<li>3</li>
		<li>4</li>
		<li>5</li>
		<li>6</li>
		<li>7</li>
		<li>8</li>
		<li>9</li>
		<li style="    font-size: 17px;">清除</li><li></li><li style="    font-size: 17px;">关闭</li>
	</ul>
</div>

<div id="maybebox100" class="maybebox">
	<ul>
		<li></li>
		<li></li>
		<li></li>
		<li></li>
		<li></li>
		<li></li>
		<li></li>
		<li></li>
		<li></li> 
	</ul>
</div>


<div  class="button" >  
	<ul>
		<li></li>
		<li>开始计算</li>
		<li></li>
		<li></li>
		<li></li>
		<li></li>
	 
	 
	</ul>
</div>

 然后是suDu.js

	var log = function(x){
			console.log(x);
		}
		var n = 0; //统计次数

		var suDu = window.sd || {};   
		suDu = (function(g) {  
			 // suDu是便于搜索。
			
			//存放数独题目
			var setData = function (data){
				this.data =  data;
			}

			// 安装行列块计算可能的数字
			var maybiNumber = function (index){ 
				var data=suDu.data.split("");
				var maybeNumber = "";
				if(data[index]==0){
					var current_H = parseInt(index/9) ; //行
					var current_L = parseInt(index%9) ;  //列
					var current_B = parseInt(current_H/3) *3 + parseInt(current_L/3);//块
					maybeNumber = "123456789";
					for (var i = 0; i < data.length; i++) {
						if(    (parseInt(i/9) ==  current_H) 
							|| (parseInt(i%9) ==  current_L) 
							|| (parseInt(parseInt(i/9)/3) *3 + parseInt(parseInt(i%9)/3) ==  current_B)     ){
							if(data[i]>0){ 
								maybeNumber = maybeNumber.replace(data[i],""); 
							}  
						} 
					} 	
				} 
				return maybeNumber;
			}
  
			// 画可能盘
			var createMaybePan = function (index) { 
				//检查为空才需要Mpan
				var data=suDu.data.split("");
				$("#maybebox" + index).remove();
				if(data[index]==0){ 
					// 制作可能框 
					var mb = $("#maybebox100").clone();
					$(mb).attr("id","maybebox" + index);  
					$(mb).css("display","block");   
					$("body").append(mb);	
					// 定位
					var shuduboxlix = $("#shudubox li").eq(index) ;
					$(mb).offset({left: $(shuduboxlix).offset().left,top:  $(shuduboxlix).offset().top}); 
					// var mn = $(shuduboxlix).attr("mb").split(""); 
					var mn = suDu.maybiNumber(index).split("");  
					for (let i = 0; i < mn.length; i++) { 
						  $("#maybebox" + index + " li").eq(mn[i]-1).html(mn[i]);
					} 
				}
				
				
			 }  
			
			var fillDataHtml = function (index,data) {
				var shuduboxli = $("#shudubox li") ; 
				$(shuduboxli[index]).html((data=="0")?"":data); 
				suDu.createMaybePan(index); 
			}
			// 填写一个数字并删除可能盘
			var fillData =  function(index,data){
				
				var arrd = suDu.data.split(""); 
				arrd[index]= data;  
				suDu.setData(arrd.join(""));  
				// fillDataHtml(index,data)

				// log("填写第"+index+"格:"+data );
				//往格子里填数字
				
				//往空格里填写可能的数字
				// $(shuduboxli[index]).attr("mb",suDu.maybiNumber(index));
				
			}

			var checkOneMaybe = function(params) {
					var hasOne = false ;
					for (var i = 0; i < 81; i++) { 
						// 检查 只有1个可能数,填写,并更新data
						var maybei = suDu.maybiNumber(i);
						if(maybei.length==1){ 
							suDu.fillData( i ,maybei);  
							hasOne = true;
							
						} 
					}
					if(hasOne){
						checkOneMaybe()
					}
			}

			var checkHlbMaybe = function(params) {
					var hasOne = false ;
					var h={H:[]}; 
					for (let index = 0; index < 27; index++) {
						var hlb = "L";
						var n = index-8; 
						if(index < 9 ){hlb="H";n=index+1;}
						if(index > 17){hlb="B" ; n = index - 17}  
						h.H.push({name:hlb,i:n,v:"",k:'',o:[]}); 
					} 
					// 统计行列块的备选数合并
					var getHLB =  function ( index) { 
							return h.H[index].v  ; 
					}
					var setHLB = function( index,value,i,maybin ) { 
							h.H[index].v= value ;  
							h.H[index].o.push({index:i,mb:maybin})
					}
					for (let i = 0; i < 81; i++) {
						var index  = i ;
						var current_H = parseInt(index/9) ; //行
						var current_L = parseInt(index%9) ;  //列
						var current_B = parseInt(current_H/3) *3 + parseInt(current_L/3);//块
						var maybin = suDu.maybiNumber(i) ;
						setHLB( current_H,	getHLB( current_H) + maybin ,i,maybin )
						setHLB(9+current_L,	getHLB(9+current_L) + maybin,i,maybin  )
						setHLB(18+ current_B,	getHLB(18+ current_B) +maybin ,i,maybin )
						// const element = array[i];
					}
					//只有先合起来才能开始分析是否有只有1个备选的。 
					
					//备选k填写进来
					for (let index = 0; index < h.H.length; index++) {
						var _arr = h.H[index].v.split("") ;
						_arr.sort();  
						var _res = []
						for (var i = 0; i < _arr.length;) {  
							var count = 0;  
							for (var j = i; j < _arr.length; j++) {  
								if (_arr[i] == _arr[j]) {  
									count++;  
								}  
							}  
							if(count==1){
								_res.push([_arr[i], count]);  
								h.H[index].k=_arr[i];
							} 
							i += count;  
						}  
					} 
					for (let index = 0; index < h.H.length; index++) {
						if( h.H[index].k.length>0 ){
							h.H[index].o.forEach((v)=>{ 
								if(v.mb.indexOf(h.H[index].k)>=0){ 
									suDu.fillData( v.index ,h.H[index].k);
									hasOne=true; 
								} 
							}) 
						} 
					}
					
					var data = suDu.data.split("");
					for (var index = 0; index < 81; index ++) { 
						suDu.fillData( index ,data[ index ]); 
					} 
					suDu.hlb=h;
					if(hasOne){
						checkHlbMaybe();
					}
			}

			var cal = function(params) {
					// 找到所有备选中最短的。 
					var historyLog  = suDu.historyLog || [];
					//获取备选中最短的index,mabe.并拆分成可能放到his中
					var minMb = {index:-1,mb:"11111111111111111111"}
					var checkHasMaybe = function (params) {
						var result = true;
						for (let i = 0; i < 81; i++) {
							if (suDu.data[i]==0){
								if(suDu.maybiNumber(i).length==0){
									result = false;
								}
							} 
						} 
						return result;
					}
					if(checkHasMaybe()){
						for (let i = 0; i < 81; i++) {
							var myb = suDu.maybiNumber(i) ;
							if(myb.length<minMb.mb.length && myb.length>0 ){
								minMb.index = i;
								minMb.mb = myb;
							}
						} 
					}
					 
					var arr_minMb = minMb.mb.split("");
					for (let i = 0; i < arr_minMb.length; i++) {
						if(minMb.index>=0){
							historyLog.push({
								"data" : suDu.data, 
								"checkWrong":true, 
								"index" :minMb.index, 
								"number":arr_minMb[i]}); 

						} 
					}
					if(historyLog.length>0){
						n++;
						log("第" + n + "次假定在:" + historyLog[historyLog.length-1].index + "的位置填写:" + historyLog[historyLog.length-1].number)
						
						suDu.setData(historyLog[historyLog.length-1].data);
						suDu.fillData(historyLog[historyLog.length-1].index,historyLog[historyLog.length-1].number)
						// log(historyLog)
						
						delete  historyLog[historyLog.length-1]
						var newHis = [];
						historyLog.forEach((v)=>{
							newHis.push(v);
						}) 
						suDu.historyLog =  newHis;
						//现在开始尝试
						
						suDu.checkOneMaybe();
						suDu.checkHlbMaybe();//  检查行列块中是否有:只有一个备选数
						if(suDu.total405(suDu.data)){
							log(suDu.data);
						}else{
							setTimeout(function (params) {
								suDu.cal();
							},0)
							
						}
					}
					
				}

			// 函数的方法
			// var fillData =  function(index,data){
			// 	var shuduboxli = $("#shudubox li") ;
			// 	//往格子里填数字
			// 	$(shuduboxli[index]).html((data=="0")?"":data); 
			// 	//往空格里填写可能的数字
			// 	// $(shuduboxli[index]).attr("mb",suDu.maybiNumber(index));
			// 	suDu.createMaybePan(index);
			// }

			// 有返回值的范例
			// var fillData = (function(index,data) { 
			// 	var shuduboxli = $("#shudubox li") ;
			// 	$(shuduboxli[index]).html((data=="0")?"":data); 
			// 	  return { init: "1" }
			// } )(); 


			var createBlank = (function() { 
				var _tmp =  "<ul class='clearfix'>";
				for (var i = 0; i < 9; i++) { 
					for (var j = 0; j < 9; j++) { 
						_tmp += "<li class='"+ (( i==2 || i==5  )?"border_bottom":"") + (((j+1)%3==0 && j!=8)?" border_right":"")  +"'>"  +"</li>";
					} 
				}
				_tmp += "</ul>"; 
				return _tmp;
			} )();

			 
			var total405 = function(data) {
				var result = false ; 
				var count=0;
				 
				var d =   data.split("");
				d.forEach((v)=>{
					// if(v==0){return false;}
					count += parseInt(v);
				})
				if(count==405){result = true;}

				return  result;
			} 

			return {
				createBlank: createBlank ,
				createMaybePan : createMaybePan,
				data : this.data,
				setData : setData,
				maybiNumber:maybiNumber,
				fillData:fillData,
				checkOneMaybe:checkOneMaybe,
				checkHlbMaybe:checkHlbMaybe,
				total405:total405,
				cal:cal
			}
		})(jQuery);

然后是启动部分。

	//   000010000008006004020000090000000270300000000604005000000070000005000003000920000
		// 946812537758396124123457698589134276312769845674285319431578962295641783867923451
	//   946812537758396124123457698589134276312769845674285319431578962295641783867923451
	//   328226
	//    010800005060030080200000060004007000030000100000500002300040900800000040009006300
	//   413862795967435281285971463624317859538629174791584632356248917872193546149756328
	//   438226
    // // var startdata ="000970000340000000806000005107095086500400200930602100712009560605724813483100970"; //    		
    // var startdata ="004602000600030004020400090980040350103000040460003807030024070040061035009300400"; //    				25197364834956872187624139512739548656841723993468215771283956469572481348315697218250"; //一道初级1
 	//  // 			 http://www.cn.sudokupuzzle.org/printable.php?nd=1&y=2017&m=11&d=1  题库可用
	//  // 			 http://www.cn.sudokupuzzle.org/online2.php?nd=0&y=2017&m=11&d=25
	//  // 			 1995-5-1~2019-12-26 共23*365*5 = 42000 题 带答案  http://www.cn.sudokupuzzle.org/online2.php?nd=0&y=2017&m=11&d=25
	//  // 			 标准数独应该有6670903752021072936960种终盘,
	//  // 			 如果将重复(如数字交换、对称等)不计算,那么有5,472,730,538个, 
 

 

	
  
	// 123456789200000000300000000400000000500000000600000000700000000800000000987645321
		suDu.setData("123456789200000000300000000400000000500000000600000000700000000800000000987645321");   
		
		$("#shudubox").html(suDu.createBlank);   //createBlank 画盘子 
				
		var data = suDu.data.split(""); // 填充Data数 
		for (var index = 0; index < 81; index ++) { 
			suDu.fillData( index ,data[ index ]); 
		}

		setTimeout(function (params) { 
			suDu.checkOneMaybe();
			suDu.checkHlbMaybe();//  检查行列块中是否有:只有一个备选数
			
		},50)
 

		// 按钮事件
		$(".button li").click(function (e) { 

			// 第二按钮,检查整行列块是否有1个可能数
			if($(this).index()==1){ 
			  suDu.cal()  
			} 
			
		})

 

	 

已经3000次了不知道能否有结果。

用这个程序已经可以解开大师级的难题了。

短短16步假定,是如何做到的呢?假定前的工作是已经放好的。

 

最后放出本程序最终版本:建议从后面看起。

	var log = function(x){
			console.log(x);
		}
		var n = 0; //统计次数

		var suDu = window.sd || {};   
		suDu = (function() {  
			 // suDu是便于搜索。
			
			//存放数独题目,通过suDu.data来获取当前的数字。setData来回溯数据
			var setData = function (data){
				this.data =  data;
			}

			// 可能的数字: index位置来计算这个格子可能的数字。
			// 如果为空则无解。如果只有一个,就可以直接填写。
			var maybiNumber = function (index){ 
				var data=suDu.data.split(""); //获取数组
				var maybeNumber = "";
				if(data[index]==0){   //检查是否是空格,有数字的就不用再计算
					var current_H = parseInt(index/9) ; //行属
					var current_L = parseInt(index%9) ;  //列属
					var current_B = parseInt(current_H/3) *3 + parseInt(current_L/3);//块属
					maybeNumber = "123456789"; //初始可能的数字串
					for (var i = 0; i < data.length; i++) {
						if(    (parseInt(i/9) ==  current_H) 
							|| (parseInt(i%9) ==  current_L) 
							|| (parseInt(parseInt(i/9)/3) *3 + parseInt(parseInt(i%9)/3) ==  current_B)     ){
							if(data[i]>0){  //逐个取出并去掉行列块中已经存在的数字,剩下的就是可能的数字
								maybeNumber = maybeNumber.replace(data[i],""); 
							}  
						} 
					} 	
				} 
				return maybeNumber; 
			}

			//改变suDu.data 用给定位置,数字
			var fillOneData =  function (index,data) {
				 
				suDu.setData( suDu.data.substr(0,parseInt(index)) + data + suDu.data.substr( parseInt(index) +1 )   ); 
			  
			}

 
			//这个是发现前面检查后还有漏的。
			// 这个就是说一行列块中的可能数全部放一起排序并统计,如果有数量为1的可能数。
			// 整行只有1个格子里有这个数,那这个格子就是这个数,其他格子都不可能是这个数
			var checkHLBMaybe = function() { 
					var h={H:[]}; 
					for (let index = 0; index < 27; index++) {
						var hlb = "L";
						var n = index-8; 
						if(index < 9 ){hlb="H";n=index+1;}
						if(index > 17){hlb="B" ; n = index - 17}  
						h.H.push({name:hlb,i:n,v:"",k:'',o:[]}); 
					} 
					// 统计行列块的备选数合并
					var getHLB =  function ( index) { 
							return h.H[index].v  ; 
					}
					var setHLB = function( index,value,i,maybin ) { 
							h.H[index].v= value ;  
							h.H[index].o.push({index:i,mb:maybin})
					}
					for (let i = 0; i < 81; i++) {
						var index  = i ;
						var current_H = parseInt(index/9) ; //行
						var current_L = parseInt(index%9) ;  //列
						var current_B = parseInt(current_H/3) *3 + parseInt(current_L/3);//块
						var maybin = suDu.maybiNumber(i) ;
						setHLB( current_H,	getHLB( current_H) + maybin ,i,maybin )
						setHLB(9+current_L,	getHLB(9+current_L) + maybin,i,maybin  )
						setHLB(18+ current_B,	getHLB(18+ current_B) +maybin ,i,maybin )
						// const element = array[i];
					}
					//只有先合起来才能开始分析是否有只有1个备选的。上面这些事是必须的。 
					
					//备选k填写进来
					for (let index = 0; index < 27; index++) {
						var _arr = h.H[index].v.split("") ;
						_arr.sort();   
						for (var i = 0; i < _arr.length;) {  
							var count = 0;  
							for (var j = i; j < _arr.length; j++) {  
								if (_arr[i] == _arr[j]) {  
									count++;  
								}  
							}  
							if(count==1){   
								h.H[index].k=_arr[i];
							} 
							i += count;  
						}  
					} 
					var result ="";
					for (let index = 0; index < h.H.length; index++) {
						if( h.H[index].k.length>0 ){
							h.H[index].o.forEach((v)=>{ 
								// 前面每次setHLB的时候是这样放进去的
								// h.H[index].o.push({index:i,mb:maybin})
								if(v.mb.indexOf(h.H[index].k)>=0){ 
									result= v.index + "_" + h.H[index].k  ; 
								} 
							}) 
						} 
					}
				    return result ;
			}

			//检查备选中是否有可用的数字,并更新之,且循环。
			var checkOneMaybe = function(params) {
					
					var hasOne = false ;
					for (var i = 0; i < 81; i++) { 
						// 检查 只有1个可能数,填写,并更新data
						var maybei = suDu.maybiNumber(i);
						if(maybei.length==1){ 
							suDu.fillOneData( i ,maybei);  
							hasOne = true; //再次计算并检查。 
						} 
					    var hlbMaybi = suDu.checkHLBMaybe(i); //返回 "0_9"
						if(hlbMaybi.length>0){ 
							suDu.fillOneData( hlbMaybi.split("_")[0],hlbMaybi.split("_")[1]);  
							hasOne = true; //再次计算并检查。 
						} 
					}
					
					 

					if(hasOne){
						checkOneMaybe();
					}
			}


			 

















  
			// 画可能盘,
			var createMaybePan = function (index) { 
				//检查为空才需要Mpan
				var data=suDu.data.split("");
				$("#maybebox" + index).remove();
				if(data[index]==0){ 
					// 制作可能框 
					var mb = $("#maybebox100").clone();
					$(mb).attr("id","maybebox" + index);  
					$(mb).css("display","block");   
					$("body").append(mb);	
					// 定位
					var shuduboxlix = $("#shudubox li").eq(index) ;
					$(mb).offset({left: $(shuduboxlix).offset().left,top:  $(shuduboxlix).offset().top}); 
					// var mn = $(shuduboxlix).attr("mb").split(""); 
					var mn = suDu.maybiNumber(index).split("");  
					for (let i = 0; i < mn.length; i++) { 
						  $("#maybebox" + index + " li").eq(mn[i]-1).html(mn[i]);
					} 
				}
				
				
			 }  
			
			var fillDataHtml = function (index,data) {
				var shuduboxli = $("#shudubox li") ; 
				$(shuduboxli[index]).html((data=="0")?"":data); 
				// suDu.createMaybePan(index); 
			}
			// 填写一个数字并删除可能盘
			var fillData =  function(index,data){
				
				var arrd = suDu.data.split(""); 
				arrd[index]= data;  
				suDu.setData(arrd.join(""));  
				  fillDataHtml(index,data)

				// log("填写第"+index+"格:"+data );
				//往格子里填数字
				
				//往空格里填写可能的数字
				// $(shuduboxli[index]).attr("mb",suDu.maybiNumber(index));
				
			}


			

			var cal = function(params) {
					// 找到所有备选中最短的进行回溯,最好是2个数的。
					var historyLog  = suDu.historyLog || [];
					//获取备选中最短的index,mabe.并拆分成可能放到his中
					var minMb = {index:-1,mb:"123456789"} ; //初始化最小位置和可能数
					
					//如果计算到有备选为空的情况说明前面有填错的了。
					var noBlankMaybe = function (params) {
						var result = true;
						for (let i = 0; i < 81; i++) {
							if (suDu.data[i]==0){
								if(suDu.maybiNumber(i).length==0){
									result = false;
								}
							} 
						} 
						return result;
					}

					//挑出最短的可选进行尝试、
					if(noBlankMaybe()){
						for (let i = 0; i < 81; i++) {
							var myb = suDu.maybiNumber(i) ;
							if(myb.length<minMb.mb.length && myb.length>0 ){
								minMb.index = i;
								minMb.mb = myb;
							}
						} 
					}
					 
					//尝试之前备份数据,和可以尝试的备选
					var arr_minMb = minMb.mb.split("");
					for (let i = 0; i < arr_minMb.length; i++) {
						if(minMb.index>=0){
							historyLog.push({
								"data" : suDu.data, 
								"checkWrong":true, 
								"index" :minMb.index, 
								"number":arr_minMb[i]}); 

						} 
					}

					if(historyLog.length>0){
						n++;
						log("第" + n + "次假定在:" + historyLog[historyLog.length-1].index + "的位置填写:" + historyLog[historyLog.length-1].number)
						
						suDu.setData(historyLog[historyLog.length-1].data);

						//如果有假定数,尝试填写一个。用后并删除它。要么成功。要么结束,回来继续填写没用过的。 
						suDu.fillOneData(historyLog[historyLog.length-1].index,historyLog[historyLog.length-1].number)
						// log(historyLog)
						
						delete  historyLog[historyLog.length-1]
						var newHis = [];
						historyLog.forEach((v)=>{
							newHis.push(v);
						}) 
						suDu.historyLog =  newHis;
						//现在开始尝试
						
						if(noBlankMaybe()){
							suDu.checkOneMaybe();
							// suDu.checkHlbMaybe();//  检查行列块中是否有:只有一个备选数
							if(suDu.total405(suDu.data)){
								log(suDu.data);
							}else{
								setTimeout(function (params) {
									suDu.cal();
								},0)
								
							}
						}
						
						
					}
					
				}

			// 函数的方法
			// var fillData =  function(index,data){
			// 	var shuduboxli = $("#shudubox li") ;
			// 	//往格子里填数字
			// 	$(shuduboxli[index]).html((data=="0")?"":data); 
			// 	//往空格里填写可能的数字
			// 	// $(shuduboxli[index]).attr("mb",suDu.maybiNumber(index));
			// 	suDu.createMaybePan(index);
			// }

			// 有返回值的范例
			// var fillData = (function(index,data) { 
			// 	var shuduboxli = $("#shudubox li") ;
			// 	$(shuduboxli[index]).html((data=="0")?"":data); 
			// 	  return { init: "1" }
			// } )(); 


			var createBlank = (function() { 
				var _tmp =  "<ul class='clearfix'>";
				for (var i = 0; i < 9; i++) { 
					for (var j = 0; j < 9; j++) { 
						_tmp += "<li class='"+ (( i==2 || i==5  )?"border_bottom":"") + (((j+1)%3==0 && j!=8)?" border_right":"")  +"'>"  +"</li>";
					} 
				}
				_tmp += "</ul>"; 
				return _tmp;
			} )();

			 
			var total405 = function(data) {
				var result = false ; 
				var count=0;
				 
				var d =   data.split("");
				d.forEach((v)=>{
					// if(v==0){return false;}
					count += parseInt(v);
				})
				if(count==405){result = true;}

				return  result;
			} 

			return {
				createBlank: createBlank ,
				createMaybePan : createMaybePan,
				data : this.data,
				setData : setData,
				maybiNumber:maybiNumber,
				fillData:fillData,
				checkOneMaybe:checkOneMaybe,
				checkHLBMaybe:checkHLBMaybe,
				total405:total405,
				cal:cal ,
				fillOneData:fillOneData,
				fillDataHtml:fillDataHtml 
			}
		})(jQuery);
		
		//只用初级的解题可以解初级的。
		//"000970000340000000806000005107095086500400200930602100712009560605724813483100970
		//"251973648349568721876241395127395486568417239934682157712839564695724813483156972"
		// 下面这个大师级的就无法解,还是要用回溯法
		// suDu.setData("004602000600030004020400090980040350103000040460003807030024070040061035009300400");  
		// 			 "004602000600030004020400090980040350103000040460003807036024070040061035019300460" 
		//            394672581651839724827415693982147356173586249465293817536924178248761935719358462
		//回溯16次后解出答案
		suDu.setData("123456789456789123789123456231000000564000000891000000312000000645000000978000000");  
		$("#shudubox").html(suDu.createBlank);
		var data = suDu.data.split(""); // 填充Data数 
		for (var index = 0; index < 81; index ++) { 
			suDu.fillDataHtml( index ,data[ index ]); 
		} 
		 
					//  "004602000600030004020400090980040350103000040460003807036024070040061035019300460" 
		suDu.checkOneMaybe(); 
		suDu.cal();
		log(suDu); 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
数独算法说明:用三个二维数组记录数独每个点的状态,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)值为一位数字,就说明该点的值是唯一的,可以确定了。重复第2步。 4、剩余的SY(i, j)中字符串长度最少也是两位,或更多位数。随机从这些两位数的SY(i, j)中选取一个点。取其中的一位确定为该点的值后,重复第2步。如果错误遇错,则重复执行第4步。直到所有点都被确定。 注意:第2步是需要多次重复执行的,所以可用递归函数完成。如果执行结果出现错误(某数出现重复,或某点无值),需要对该过程所执行的所有操作进行回退。 第4步也是需要重复执行的。本程序用Goto跳转方式实现多次执行。 简单的数独,要么所有的点都具有唯一值,第1步执行完成后,就已全部完成。或者具有多个解,随意猜测一个二位数的SY(i, j)的值都能成功。 难的数独是:可唯一确定的点很少,大部分点都有两种或多种可能的值,但最终正确答案只有一种或很少种解。 软件在自动计算过程中,具有很大的偶然性,对于骨灰级的数独题目在计算过程中,时间短的可能不到1秒就能完成,长的可能要几分钟,需要将各种可能性都测试一遍才会有结果。 只要题目正确,多计算几次就能得到答案。 软件是VB6.0开发的,只用到MSHFLXGD控件用于显示。程序只处理各点有两种可能值的情况,对只存在三种可能值的情况未进一步处理,该情况非常极端了。 软件可以保存布局,可选择预存的关数,退出时自动保存界面状态。程序在用到配置文件枚举方法、表格编辑、递归函数等,可作入门级学习研究。 软件可以进一步修改拓展,增加对数独题目难容度的判断等功能。 软件中自带网上下载的200个数独题目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东宇科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值