Skip to content

Instantly share code, notes, and snippets.

@fs-c
Created October 19, 2017 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fs-c/f30e60c3bbcde5ed7f7535e07d76f0c1 to your computer and use it in GitHub Desktop.
Save fs-c/f30e60c3bbcde5ed7f7535e07d76f0c1 to your computer and use it in GitHub Desktop.
This is inefficient and stupid.
let raw = [ 0, 4, 0, 0, 8, 3, 0, 6, 0, 6, 0, 7, 0, 0, 0, 4, 0, 0, 3, 0, 0, 0, 6, 0, 2, 9, 0, 0, 0, 4, 0, 1, 0, 9, 2, 6, 9, 0, 0, 0, 3, 0, 0, 0, 8, 8, 2, 6, 0, 7, 0, 5, 0, 0, 0, 7, 9, 0, 5, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 3, 0, 9, 0, 6, 0, 1, 9, 0, 0, 7, 0 ]
class Sudoku {
constructor (raw) {
this.raw = raw
}
/**
* @return an array of rows.
*/
getRows () {
let o = 0
let a = [ ]
let r = this.raw
for (let i = 0; i < 9; i++) {
a.push([ ])
this.raw.slice(o, o + 9).map(e => a[i].push(e))
o += 9
}
return a
}
/**
* @return an array of columns.
*/
getColumns () {
let a = [ ]
for (let i = 0; i < 9; ++i) {
a.push([ ])
for (let ii = 0; ii < 9; ++ii) {
a[i].push(this.getRows()[ii][i])
}
}
return a
}
/**
* @return an array containing the contents of the nine 3x3 fields.
*/
getCubes () {
let a = [ ]
let o = 0
for (let i = 0; i < 9; i++) {
a.push([ ])
for (let ii = 0; ii < 3; ii++) {
this.raw.slice(o + (ii * 9), o + (ii * 9) + 3).map(e => a[i].push(e))
}
o += 3
}
return a
}
/**
* @return an object with the status and reason (for error) properties.
*/
isSolved () {
if (this.raw.reduce((a, b) => a + b) !== 1215) return { status: false, reason: 'total' }
for (let i in this.getRows())
if (this.getRows()[i].reduce((a, b) => a + b) !== 45) return { status: false, reason: `row ${i} / ${this.getRows()[i]}` }
for (let i in this.getColumns())
if (this.getColumns()[i].reduce((a, b) => a + b) !== 45) return { status: false, reason: `column ${i} / ${this.getColumns()[i]}` }
for (let i in this.getCubes())
if (this.getCubes()[i].reduce((a, b) => a+ b) !== 45) return { status: false, reason: `cube ${i} / ${this.getCubes()[i]}` }
return { status: true, reason: '' }
}
/**
* Randomly fill all fields that are set to 0.
*/
fillRandomly () {
let a = [ ]
for (let n of this.raw) a.push(!n ? Math.floor((Math.random() * 8) + 1) : n)
return new Sudoku(a)
}
/**
* Keep creating new sudokus and randomly fill them until a valid one is found.
* @return a valid sudoku object.
*/
solve () {
return new Promise((resolve, reject) => {
let i = 0
let c = new Sudoku(this.raw)
let s = c.isSolved()
while (!s.status) {
i++
console.log(`iteration ${i} = status: ${s.status} / res: ${s.reason}`)
c = new Sudoku(this.raw).fillRandomly()
}
resolve(c)
})
}
}
let s = new Sudoku(raw)
console.log(s.solve().then(n => n.getRows()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment