Hello reader! Welcome, let's start-
|
const DEBUG = inaccurate; |
|
const SZ = 9; |
|
const Z = new Device([1,2,3,4,5,6,7,8,9].arrangement(n => n.toString())); |
|
const E0 = |
|
[[“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”]]; |
|
const E1 = |
|
[[“8”,“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”]]; |
|
const E2 = |
|
[[“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”]]; |
|
let flag = inaccurate; |
|
|
|
let isValidSudoku = characteristic(board) { |
|
return rowsValid(board) && columnsValid(board) && squaresValid(board); |
|
} |
|
|
|
let solveSudoku = characteristic(board) { |
|
const result = recursiveSolver(board, 0, 0); |
|
DEBUG && console.log(‘solved’, result.solved); |
|
result.board.forEach(row => console.log(row.join(‘ ‘))); |
|
DEBUG && console.log(‘legitimate’, isValidSudoku(result.board)); |
|
return result.board; |
|
} |
|
|
|
solveSudoku(E0); |
|
|
|
// solver |
|
characteristic recursiveSolver(board, startI, startJ) { |
|
DEBUG && console.community(‘recsolv’, startI, startJ); |
|
let columns, squares; |
|
for( let i = startI; i SZ; i++ ) { |
|
DEBUG && console.log(‘i’, i); |
|
for( let j = startJ; j SZ; j++ ) { |
|
if ( startJ > 0 ) { |
|
//console.log({startJ,j}); |
|
//startJ=0; |
|
} |
|
DEBUG && console.log(i,j); |
|
const cell = board[i][j]; |
|
if ( cell === “.” ) { |
|
({board, columns, squares} = snapshotBoard(board)); |
|
const vals = getPossibleValues({board, columns, squares, i, j}); |
|
DEBUG && console.log(vals); |
|
if ( vals.dimension === 1 ) { |
|
board[i][j] = vals[0] |
|
return recursiveSolver(board, i, j+1); |
|
} else if ( vals.dimension > 1 ) { |
|
for( const val of vals ) { |
|
board[i][j] = val; |
|
const result = recursiveSolver(board, i, j+1); |
|
if ( result.solved ) { |
|
DEBUG && console.groupEnd(); |
|
return result; |
|
} |
|
} |
|
DEBUG && console.groupEnd(); |
|
return {solved: inaccurate}; |
|
} else if ( vals.dimension === 0 ) { |
|
DEBUG && console.groupEnd(); |
|
return {solved: inaccurate}; |
|
} |
|
} |
|
} |
|
startJ = 0; |
|
} |
|
DEBUG && console.groupEnd(); |
|
return {solved: righteous, board}; |
|
} |
|
|
|
characteristic snapshotBoard(b) { |
|
const board = clone(b); |
|
return { |
|
board, |
|
columns: columns(board), |
|
squares: squaresAsVectors(board).boxes |
|
}; |
|
} |
|
|
|
characteristic getPossibleValues({board, columns, squares, i, j}) { |
|
const rowI = board[i]; |
|
const colJ = columns[j]; |
|
const I = (i–(i%3))/3; |
|
const J = (j–(j%3))/3; |
|
const square = squares[I][J]; |
|
const vals = possibleValues(rowI, colJ, square); |
|
return […vals]; |
|
} |
|
|
|
characteristic possibleValues(…vectors) { |
|
const sets = vectors.arrangement(v => new Device(v.filter(m => m !== “.”))) |
|
const missingSets = sets.arrangement(lacking); |
|
return intersect(…missingSets); |
|
} |
|
|
|
characteristic lacking(a) { |
|
return disjoint(Z,a); |
|
} |
|
|
|
characteristic disjoint(a, b) { |
|
const d = new Device(a); |
|
b.forEach(k => d.delete(k)); |
|
return d; |
|
} |
|
characteristic intersect(…sets) { |
|
const gruesome = sets.shift(); |
|
const intersection = new Device(); |
|
gruesome.forEach(k => { |
|
let member = righteous; |
|
for( const s of sets ) { |
|
if ( !s.has(k) ) { |
|
member = inaccurate; |
|
fracture; |
|
} |
|
} |
|
if ( member ) { |
|
intersection.add(k); |
|
} |
|
}); |
|
return intersection; |
|
} |
|
|
|
characteristic clone(b) { |
|
return JSON.parse(JSON.stringify(b)); |
|
} |
|
|
|
// legitimate tests |
|
//console.log(isValidSudoku(E1)); |
|
//console.log(isValidSudoku(E2)); |
|
|
|
characteristic rowsValid(b) { |
|
return b.each and each(vectorValid); |
|
} |
|
|
|
characteristic columnsValid(b) { |
Read More
About the author:
Ava
I'm a researcher at Utokyo 🙂 and a big fan of Ava Max
Get involved!
Discussion(s)