Showing
1 changed file
with
37 additions
and
34 deletions
| ... | @@ -2,13 +2,13 @@ | ... | @@ -2,13 +2,13 @@ |
| 2 | * @param {character[][]} board | 2 | * @param {character[][]} board |
| 3 | * @return {void} Do not return anything, modify board in-place instead. | 3 | * @return {void} Do not return anything, modify board in-place instead. |
| 4 | */ | 4 | */ |
| 5 | -var solveSudoku = function(board) { | 5 | +var solveSudoku = function (board) { |
| 6 | let empty = {}; | 6 | let empty = {}; |
| 7 | - let rows = new Array(9).fill(void 0).map(()=>new Set()); | 7 | + let rows = new Array(9).fill(void 0).map(() => new Set()); |
| 8 | - let cols = new Array(9).fill(void 0).map(()=>new Set()); | 8 | + let cols = new Array(9).fill(void 0).map(() => new Set()); |
| 9 | - let blocks = new Array(9).fill(void 0).map(()=>new Set()); | 9 | + let blocks = new Array(9).fill(void 0).map(() => new Set()); |
| 10 | 10 | ||
| 11 | - for (let i=0;i<9;i++) { | 11 | + for (let i = 0; i < 9; i++) { |
| 12 | for (let j = 0; j < 9; j++) { | 12 | for (let j = 0; j < 9; j++) { |
| 13 | let block = block_no(i, j); | 13 | let block = block_no(i, j); |
| 14 | let v = board[i][j]; | 14 | let v = board[i][j]; |
| ... | @@ -16,55 +16,53 @@ var solveSudoku = function(board) { | ... | @@ -16,55 +16,53 @@ var solveSudoku = function(board) { |
| 16 | rows[i].add(v); | 16 | rows[i].add(v); |
| 17 | cols[j].add(v); | 17 | cols[j].add(v); |
| 18 | blocks[block].add(v); | 18 | blocks[block].add(v); |
| 19 | - mark({block, i, j}, v); | ||
| 20 | - } else { | ||
| 21 | - mark({block, i, j}, v); | ||
| 22 | } | 19 | } |
| 20 | + mark({ block, i, j }, v); | ||
| 23 | } | 21 | } |
| 24 | } | 22 | } |
| 25 | 23 | ||
| 26 | function block_no(i, j) { | 24 | function block_no(i, j) { |
| 27 | - return (~~(i/3))*3 + ~~(j/3); | 25 | + return (~~(i / 3)) * 3 + ~~(j / 3); |
| 28 | } | 26 | } |
| 29 | - function mark({block, i, j}, v) { | 27 | + function mark({ block, i, j }, v) { |
| 30 | - for (let n=0;n<9;n++){ | 28 | + for (let n = 0; n < 9; n++) { |
| 31 | - // not empty cell | 29 | + // skip self if is not empty cell |
| 32 | if ((i === n || j === n) && v !== '.') { | 30 | if ((i === n || j === n) && v !== '.') { |
| 33 | - if (empty[i+','+j]) { | 31 | + if (empty[i + ',' + j]) { |
| 34 | - delete empty[i+','+j]; | 32 | + delete empty[i + ',' + j]; |
| 35 | } | 33 | } |
| 36 | continue; | 34 | continue; |
| 37 | } | 35 | } |
| 38 | 36 | ||
| 39 | // cols | 37 | // cols |
| 40 | if (board[i][n] === '.') { | 38 | if (board[i][n] === '.') { |
| 41 | - let e = empty[i+','+n] = empty[i+','+n] || {block: block_no(i, n), i, j:n, maybe: new Set(['1','2','3','4','5','6','7','8','9'])}; | 39 | + let e = empty[i + ',' + n] = empty[i + ',' + n] || { block: block_no(i, n), i, j: n, maybe: new Set(['1', '2', '3', '4', '5', '6', '7', '8', '9']) }; |
| 42 | - e.maybe.delete(v); | 40 | + e.maybe.has(v)&&e.maybe.delete(v); |
| 43 | if (!e.maybe.size) { | 41 | if (!e.maybe.size) { |
| 44 | - delete empty[i+','+n]; | 42 | + delete empty[i + ',' + n]; |
| 45 | } | 43 | } |
| 46 | } | 44 | } |
| 47 | 45 | ||
| 48 | // rows | 46 | // rows |
| 49 | if (board[n][j] === '.') { | 47 | if (board[n][j] === '.') { |
| 50 | - let e = empty[n+','+j] = empty[n+','+j] || {block: block_no(n, j), i:n, j, maybe: new Set(['1','2','3','4','5','6','7','8','9'])}; | 48 | + let e = empty[n + ',' + j] = empty[n + ',' + j] || { block: block_no(n, j), i: n, j, maybe: new Set(['1', '2', '3', '4', '5', '6', '7', '8', '9']) }; |
| 51 | - e.maybe.delete(v); | 49 | + e.maybe.has(v)&&e.maybe.delete(v); |
| 52 | if (!e.maybe.size) { | 50 | if (!e.maybe.size) { |
| 53 | - delete empty[n+','+j]; | 51 | + delete empty[n + ',' + j]; |
| 54 | } | 52 | } |
| 55 | } | 53 | } |
| 56 | 54 | ||
| 57 | // blocks | 55 | // blocks |
| 58 | - let bi = ~~(block/3); | 56 | + let bi = ~~(block / 3); |
| 59 | let bj = block % 3; | 57 | let bj = block % 3; |
| 60 | - for (let bn=0;bn<9;bn++) { | 58 | + for (let bn = 0; bn < 9; bn++) { |
| 61 | - let i = bi*3 + ~~(bn/3); | 59 | + let i = bi * 3 + ~~(bn / 3); |
| 62 | - let j = bj*3 + bn % 3; | 60 | + let j = bj * 3 + bn % 3; |
| 63 | if (board[i][j] === '.') { | 61 | if (board[i][j] === '.') { |
| 64 | - let e = empty[i+','+j] = empty[i+','+j] || {block: block_no(i, j), i, j, maybe: new Set(['1','2','3','4','5','6','7','8','9'])}; | 62 | + let e = empty[i + ',' + j] = empty[i + ',' + j] || { block: block_no(i, j), i, j, maybe: new Set(['1', '2', '3', '4', '5', '6', '7', '8', '9']) }; |
| 65 | - e.maybe.delete(v); | 63 | + e.maybe.has(v)&&e.maybe.delete(v); |
| 66 | if (!e.maybe.size) { | 64 | if (!e.maybe.size) { |
| 67 | - delete empty[i+','+j]; | 65 | + delete empty[i + ',' + j]; |
| 68 | } | 66 | } |
| 69 | } | 67 | } |
| 70 | } | 68 | } |
| ... | @@ -73,7 +71,7 @@ var solveSudoku = function(board) { | ... | @@ -73,7 +71,7 @@ var solveSudoku = function(board) { |
| 73 | 71 | ||
| 74 | function fill(i, j, block, v) { | 72 | function fill(i, j, block, v) { |
| 75 | board[i][j] = v; | 73 | board[i][j] = v; |
| 76 | - empty[i+','+j].value = v; | 74 | + empty[i + ',' + j].value = v; |
| 77 | rows[i].add(v); | 75 | rows[i].add(v); |
| 78 | cols[j].add(v); | 76 | cols[j].add(v); |
| 79 | blocks[block].add(v); | 77 | blocks[block].add(v); |
| ... | @@ -81,23 +79,25 @@ var solveSudoku = function(board) { | ... | @@ -81,23 +79,25 @@ var solveSudoku = function(board) { |
| 81 | 79 | ||
| 82 | function unfill(i, j, block, v) { | 80 | function unfill(i, j, block, v) { |
| 83 | board[i][j] = '.'; | 81 | board[i][j] = '.'; |
| 84 | - empty[i+','+j].value = void 0; | 82 | + empty[i + ',' + j].value = void 0; |
| 85 | rows[i].delete(v); | 83 | rows[i].delete(v); |
| 86 | cols[j].delete(v); | 84 | cols[j].delete(v); |
| 87 | blocks[block].delete(v); | 85 | blocks[block].delete(v); |
| 88 | } | 86 | } |
| 89 | 87 | ||
| 90 | function deal() { | 88 | function deal() { |
| 91 | - let blanks = Object.keys(empty).map(k=>empty[k]).filter(m=>!m.value).sort((a,b)=>{ | 89 | + // find empty cell order by maybe size |
| 90 | + let blanks = Object.keys(empty).map(k => empty[k]).filter(e => !e.value).sort((a, b) => { | ||
| 92 | return a.maybe.size - b.maybe.size; | 91 | return a.maybe.size - b.maybe.size; |
| 93 | }); | 92 | }); |
| 94 | 93 | ||
| 95 | for (let e of blanks) { | 94 | for (let e of blanks) { |
| 96 | - let {block, i, j, value} = e; | 95 | + let { block, i, j, value } = e; |
| 97 | - if (value) {continue;} | 96 | + if (value) { continue; } // maybe signed |
| 98 | let union = new Set([...rows[i], ...cols[j], ...blocks[block]]); | 97 | let union = new Set([...rows[i], ...cols[j], ...blocks[block]]); |
| 99 | - let maybe = new Set(['1','2','3','4','5','6','7','8','9'].filter(v=>!union.has(v))); | 98 | + let maybe = new Set(['1', '2', '3', '4', '5', '6', '7', '8', '9'].filter(v => !union.has(v))); |
| 100 | 99 | ||
| 100 | + // empty cell must has some maybe number | ||
| 101 | if (!maybe.size) { | 101 | if (!maybe.size) { |
| 102 | return false; | 102 | return false; |
| 103 | } | 103 | } |
| ... | @@ -127,6 +127,9 @@ var solveSudoku = function(board) { | ... | @@ -127,6 +127,9 @@ var solveSudoku = function(board) { |
| 127 | deal(); | 127 | deal(); |
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| 130 | -var sudoku = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]; | 130 | +// var sudoku = [["5", "3", ".", ".", "7", ".", ".", ".", "."], ["6", ".", ".", "1", "9", "5", ".", ".", "."], [".", "9", "8", ".", ".", ".", ".", "6", "."], ["8", ".", ".", ".", "6", ".", ".", ".", "3"], ["4", ".", ".", "8", ".", "3", ".", ".", "1"], ["7", ".", ".", ".", "2", ".", ".", ".", "6"], [".", "6", ".", ".", ".", ".", "2", "8", "."], [".", ".", ".", "4", "1", "9", ".", ".", "5"], [".", ".", ".", ".", "8", ".", ".", "7", "9"]]; |
| 131 | +var sudoku = [[".","6",".","5","9","3",".",".","."],["9",".","1",".",".",".","5",".","."],[".","3",".","4",".",".",".","9","."],["1",".","8",".","2",".",".",".","4"],["4",".",".","3",".","9",".",".","1"],["2",".",".",".","1",".","6",".","9"],[".","8",".",".",".","6",".","2","."],[".",".","4",".",".",".","8",".","7"],[".",".",".","7","8","5",".","1","."]]; | ||
| 132 | +console.time(); | ||
| 131 | solveSudoku(sudoku); | 133 | solveSudoku(sudoku); |
| 132 | console.info(sudoku); | 134 | console.info(sudoku); |
| 135 | +console.timeEnd(); | ... | ... |
-
Please register or login to post a comment