Skip to content

Instantly share code, notes, and snippets.

@WesleyDRobinson
Last active May 9, 2018 04:36
Show Gist options
  • Save WesleyDRobinson/cc339f4ec53039db2036542175213197 to your computer and use it in GitHub Desktop.
Save WesleyDRobinson/cc339f4ec53039db2036542175213197 to your computer and use it in GitHub Desktop.
sudoku checker
/* Please write the following function:
is_valid_solution(string grid) => boolean
The input, grid, is a string representing a grid starting in the top­left corner and moving row­by­row down to the bottom­right.
For instance, the (valid) grid pictured above would be:
grid = "835416927296857431417293658569134782123678549748529163652781394981345276374962815"
The output is a boolean representing whether it is a valid solution.
*/
module.exports = is_valid_solution
function is_valid_solution(grid) {
// early exit conditions:
// is not a string, is not 81 characters long, contains characters other than 1-9
if (typeof grid !== 'string' || grid.length !== 81 || grid.replace(/[1-9]/g, '').length !== 0 ) return false
let rows = getRowsFromGridString(grid) // [ [ n1, n2, ..., n9 ], [row2], ..., [row9] ]
let columns = transposeRowsToColumns(rows) // [ [ n1, n2, ..., n9 ], [col2], ..., [col9] ]
// check rows, columns and 3x3 boxes; if any are false
return checkForDupes(rows) && checkForDupes(columns) && checkAllBoxesForDupes(rows)
}
// helper functions
function getRowsFromGridString(string) {
let arr = []
for (let i = 0; i < string.length; i += 9) {
// slice off 9 characters and split
let row = string.slice(i, i + 9).split('')
arr.push(row)
}
return arr;
}
function transposeRowsToColumns(nestedArray) {
return nestedArray[0].map((row, i) => nestedArray.map(col => col[i]))
}
function checkForDupes(array) {
let ret = true
array.forEach((row) => {
row.forEach((n, i) => {
if (row.includes(n, i + 1)) ret = false
})
})
return ret
}
// check each 3x3 box for duplicates
// returns false if duplicates exist
function checkAllBoxesForDupes(grid) {
// rows
for (let rowStart = 0; rowStart < grid.length; rowStart += 3) {
// columns
for (let colStart = 0; colStart < grid.length; colStart += 3) {
if (!checkOneBox(grid, rowStart, colStart)) return false
}
}
return true
}
// inspect a square for dupes, default 3x3
// returns false if duplicates exist
function checkOneBox(grid, rowStart, colStart, squareLen = 3) {
let check = ''
// rows
for (let i = rowStart; i < rowStart + squareLen; i += 1) {
// columns
for (let j = colStart; j < colStart + squareLen; j += 1) {
let curr = grid[i][j]
if (check.includes(curr)) return false
else check += curr
}
}
return true
}
// quick testing
const assert = require('assert')
// no dupes; valid puzzle
assert.equal(is_valid_solution("835416927296857431417293658569134782123678549748529163652781394981345276374962815"), true)
// invalid inputs
assert.equal(is_valid_solution('hello'), false)
assert.equal(is_valid_solution(null), false)
assert.equal(is_valid_solution(835416927296857431417293658569134782123678549748529163652781394981345276374962815), false)
assert.equal(is_valid_solution("035416927296857431417293658569134782123678549748529163652781394981345276374962815"), false)
// dupe in row: 0,0 && 1,0 === 8
assert.equal(is_valid_solution("885416927296857431417293658569134782123678549748529163652781394981345276374962815"), false)
// dupe in row: 8,9 && 9,9 === 1
assert.equal(is_valid_solution("835416927296857431417293658569134782123678549748529163652781394981345276374962811"), false)
// dupe in column: 0,0 && 0,1 === 8
assert.equal(is_valid_solution("835416927896857431417293658569134782123678549748529163652781394981345276374962815"), false)
// dupe in column: 9,8 && 9,9 === 5
assert.equal(is_valid_solution("835416927296857431417293658569134782123678549748529163652781394981345275374962815"), false)
// dupe in 3x3 box: 0,0 && 3,3 === 8
assert.equal(is_valid_solution("835416927296857431418293658569134782123678549748529163652781394981345276374962815"), false)
// dupe in 3x3 box: 6,6 && 9,9 === 5
assert.equal(is_valid_solution("835416927296857431417293658569134782123678549748529163652781594981345276374962815"), false)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment