javascript实现数独解法

javascript实现数独解法为什么 80 的码农都做不了架构师 gt gt gt

研究下,挺有意思

var Sudoku = { init: function (str) { this.blank = []; this.fixed = []; this.cell = []; this.trials=[]; for (i = 0; i < 81; i++) { var chr = str.charCodeAt(i); if (chr == 48) { this.cell[i] = 511; this.blank.push(i); } else { this.cell[i] = 1 << chr - 49; this.fixed.push(i); } } }, showBoard: function () { var board = ""; for (var i = 0; i < 81; i++) { if (i % 9 == 0) { board = board.concat("\n"); } board = board.concat("["); for (var j = 0; j < 9; j++) { if ((this.cell[i] >> j & 1) == 1) { board = board.concat(String.fromCharCode(j + 49)); } } board = board.concat("]"); } return board; }, check: function () { var checkpoint = [0, 12, 24, 28, 40, 52, 56, 68, 80]; for (var i in checkpoint) { var r, b, c; r = b = c = this.cell[checkpoint[i]]; for (j = 0; j < 8; j++) { c ^= this.cell[this.getX(checkpoint[i])[j]]; b ^= this.cell[this.getX(checkpoint[i])[8 + j]]; r ^= this.cell[this.getX(checkpoint[i])[16 + j]]; } if ((r & b & c) != 0x1FF) { return false; } } return true; }, bitCount: function (i) { var n = 0; for (var j = 0; j < 9; j++) { if ((i >> j & 1) == 1) n++; } return n; }, numberOfTrailingZeros: function(i){ var n = 0; for (var j = 0; j < 9; j++) { if ((i >> j & 1) ==0) n++; else{ break; } } return n; }, updateCandidates: function () { for (var i in this.fixed) { var opt = 0x1FF ^ this.cell[this.fixed[i]]; for (var j = 0; j < 24; j++) { this.cell[this.getX(this.fixed[i])[j]] &= opt; //!notice if (this.cell[this.getX(this.fixed[i])[j]] == 0) { //console.log("Error-0 candidate:"+x[this.fixed[i]][j]); return false; } } } return true; }, seekUniqueCandidate: function () { for (var bidx in this.blank) { var row = 0, col = 0, box = 0; for (i = 0; i < 8; i++) { row |= this.cell[this.getX(this.blank[bidx])[i]]; box |= this.cell[this.getX(this.blank[bidx])[8 + i]]; col |= this.cell[this.getX(this.blank[bidx])[16 + i]]; } if (this.bitCount(this.cell[this.blank[bidx]] & ~row) == 1) { this.cell[this.blank[bidx]] &= ~row; continue; } if (this.bitCount(this.cell[this.blank[bidx]] & ~col) == 1) { this.cell[this.blank[bidx]] &= ~col; continue; } if (this.bitCount(this.cell[this.blank[bidx]] & ~box) == 1) { this.cell[this.blank[bidx]] &= ~box; } } }, seekFilledable: function () { this.fixed = []; var _del=[]; for (var i in this.blank) { if (this.bitCount(this.cell[this.blank[i]]) == 1) { this.fixed.push(this.blank[i]); //console.log("fixed:"+this.blank[i]+"=>"+this.cell[this.blank[i]]); //this.blank.splice(i, 1);//to delete it in the loop would cause bug _del.push(i); } } while(_del.length>0){ this.blank.splice(_del.pop(), 1); } }, seekMutexCell: function () { var two = []; for (var n in this.blank) { if (this.bitCount(this.cell[this.blank[n]]) == 2) { two.push(this.blank[n]); } } for (var i = 0; i < two.length; i++) { for (var j = i + 1; j < two.length; j++) { if (this.cell[two[i]] == this.cell[two[j]]) { var opt = ~this.cell[two[i]]; if (parseInt(two[i] / 9) ==parseInt(two[j] / 9)) { for (n = 0; n < 8; n++) { this.cell[this.getX(two[i])[n]] &= opt; } } if ((two[i] - two[j]) % 9 == 0) { for (n = 8; n < 16; n++) { this.cell[this.getX(two[i])[n]] &= opt; } } if ((parseInt(two[i] / 27) * 3 + parseInt(two[i] % 9 / 3)) == (parseInt(two[j] / 27) * 3 + parseInt(two[j] % 9 / 3))) { for (n = 16; n < 24; n++) { this.cell[this.getX(two[i])[n]] &= opt; } } this.cell[two[j]] = ~opt; } } } }, basicSolve: function () { do { if (!this.updateCandidates(this.fixed)) { this.backForward(); } this.seekUniqueCandidate(); this.seekMutexCell(); this.seekFilledable(); } while (this.fixed.length != 0); return this.blank.length == 0; }, setTrialCell: function() { for (var i in this.blank) { if (this.bitCount(this.cell[this.blank[i]]) == 2) { var trialValue = 1 << this.numberOfTrailingZeros(this.cell[this.blank[i]]); var waitingValue = this.cell[this.blank[i]] ^ trialValue; //console.log("try:[" + this.blank[i] + "]->" + (this.numberOfTrailingZeros(trialValue) + 1) + "#" + (this.numberOfTrailingZeros(waitingValue) + 1)); this.cell[this.blank[i]] = trialValue; this.trials.push(this.createTrialPoint(this.blank[i], waitingValue, this.cell)); return true; } } return false; }, backForward: function() { if (this.trials.length==0) { console.log("Maybe no solution!"); return; } var back = this.trials.pop(); this.reset(back.data); this.cell[back.idx] = back.val; this.fixed.push(back.idx); //console.log("back:[" + back.idx + "]->" + (this.numberOfTrailingZeros(back.val) + 1)); }, reset: function(data) { this.blank=[]; this.fixed=[]; this.cell=data.concat(); for (var i = 0; i < 81; i++) { if (this.bitCount(this.cell[i]) != 1) { this.blank.push(i); } else { this.fixed.push(i); } } }, trialSolve: function() { while (this.blank.length!=0) { if (this.setTrialCell()) { this.basicSolve(); } else { if (this.trials.length==0) { //console.log("Can't go backforward! Maybe no solution!"); break; } else { this.backForward(); this.basicSolve(); } } } }, play: function() { console.log(this.showBoard()); var start = new Date().getMilliseconds(); if (!this.basicSolve()) { this.trialSolve(); } var end = new Date().getMilliseconds(); console.log(this.showBoard()); if (this.check()) { console.log("[" + (end - start) + "ms OK!]"); } else { console.log("[" + (end - start) + "ms, cannot solve it?"); } //return this.showBoard(); }, getX:function(idx){ var neighbors=new Array(24); var box=new Array(0,1,2,9,10,11,18,19,20); var r=parseInt(idx/9); var c=idx%9; var xs=parseInt(idx/27)*27+parseInt(idx%9/3)*3; var i=0; for(var n=0;n<9;n++){ if(n==c)continue; neighbors[i++]=r*9+n; } for(var n=0;n<9;n++){ if(n==r)continue; neighbors[i++]=c+n*9; } for(var n=0;n<9;n++){ var t=xs+box[n]; if(t==idx)continue; neighbors[i++]=t; } return neighbors; }, createTrialPoint:function(idx, val, board) { var tp = {}; tp.idx = idx; tp.val = val; tp.data = board.concat(); return tp; } }; //Sudoku.init("000000000000060"); //Sudoku.init("00000"); Sudoku.init("000000000000400"); Sudoku.play(); 

转载于:https://my.oschina.net/wolfx/blog/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/204193.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 下午8:47
下一篇 2026年3月19日 下午8:47


相关推荐

  • 八数码问题简单解决办法

    八数码问题简单解决办法问题分析:八数码问题是一个经典的BFS问题,把棋局看成一个状态图,共有9!种状态。从初始棋局开始,每次转移到下个状态,直到目标棋局为止。仔细分析可知,八数码的关键是判重,如果不去除重复状态,程序会产生很多无效状态,从而复杂度大大增加解决算法:BFS+Cantor案例分析:(0表示空格所在位置)初始棋局:|1|2|3||0|8|4||7|6|5|目标棋局:|1|0|…

    2022年7月12日
    28
  • PS2手柄移植到STM32上面的小笔记[通俗易懂]

    PS2手柄移植到STM32上面的小笔记[通俗易懂]一、硬件准备:战舰开发板、PS2手柄接收器、PS2手柄、连接线二、硬件连接:PS2手柄接收器有六个引脚,和单片机连接IO口连接,如下图:接收器信号单片机IOGNDGNDVCC3.3VDI/DATPB12DO/CMDPB13CSPB14CLKPB15三、PS2通信简介通讯时序如下,感觉和SPI很像,也是四线DI与DO是一对同时传输的8bit串行数据,传输的时候需要CS为低电平,CLK由高变低。DO是单片机发送给接收器的信号。

    2022年6月11日
    57
  • android 打开相册_安卓系统照片在哪个存储文件中

    android 打开相册_安卓系统照片在哪个存储文件中在GoogleNexus7(Version4.4.2)平板出现之前,Intent.ACTION_GET_CONTENT打开相册会返回如下形式的Uri: content://media/external/images/media/3951,  使用ContentResolver查询MediaStore.Images.Media.DATA就可以找文件

    2025年11月13日
    4
  • 开始了!!!

    开始了!!!

    2021年8月2日
    65
  • Android游戏引擎_巨星引擎网络公司

    Android游戏引擎_巨星引擎网络公司学Android游戏开发的朋友,往往会显得有些无所适从,他们常常不知道该从何处入手,每当遇到自己无法解决的难题时,又往往会一边羡慕于iPhone下有诸如Cocos2d-iphone之类的免费游戏引擎可供使用,一边自暴自弃的抱怨Android平台游戏开发难度太高,又连个像样的游戏引擎也没有,甚至误以为使用Java语言开发游戏是一件费力不讨好且没有出路的事情。事实上,这种想法完全是没有必要且不

    2025年11月27日
    4
  • 使用frp配置内网访问(穿透)教程(超详细,简单)

    使用frp配置内网访问(穿透)教程(超详细,简单)1Frp 介绍 frp 是一个开源 简洁易用 高性能的内网穿透和反向代理软件 支持 tcp udp http https 等协议 frp 项目官网是 https github com fatedier frp frp 工作原理服务端运行 监听一个主端口 等待客户端的连接 客户端连接到服务端的主端口 同时告诉服务端要监听的端口和转发类型 服务端 fork 新的进程监听客户端指定的端口 外网用户连接到客户端指定的端口 服务端通过和客户端的连接将数据转发到客户端 客户端进程再将数据转发到本地服务

    2026年3月26日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号