Skip to content

Instantly share code, notes, and snippets.

@kyleshevlin
Last active May 22, 2017 23:28
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 kyleshevlin/c349376fc7d29389409a3287bf160d02 to your computer and use it in GitHub Desktop.
Save kyleshevlin/c349376fc7d29389409a3287bf160d02 to your computer and use it in GitHub Desktop.
Sudoku Validator
// Given the grid below, create a function that determines
// if the grid is a valid sudoku
const grid = [
['.', '.', '.', '1', '4', '.', '.', '2', '.'],
['.', '.', '6', '.', '.', '.', '.', '.', '.'],
['.', '.', '.', '.', '.', '.', '.', '.', '.'],
['.', '.', '1', '.', '.', '.', '.', '.', '.'],
['.', '6', '7', '.', '.', '.', '.', '.', '9'],
['.', '.', '.', '.', '.', '.', '8', '1', '.'],
['.', '3', '.', '.', '.', '.', '.', '.', '6'],
['.', '.', '.', '.', '.', '7', '.', '.', '.'],
['.', '.', '.', '5', '.', '.', '.', '7', '.']
]
// Rules for validation
// In a sudoku, each row, column and cell (designated 3x3 boxes)
// must have the numbers 1-9 and only once
//
// I am not solving the sudoku, so I'm making the assumption
// that currently we are concerned with uniqueness
// Thus, if we filter the dots, we can test that each number
// in each array is unique. If it is unique, thus far we have a
// valid sudoku
function validateSudoku (grid) {
return validateRows(grid) && validateColumns(grid) && validateCells(grid)
}
function validateRows (grid) {
return grid.map(row => validatePart(row)).reduce(reduceBools, true)
}
function validateColumns (grid) {
const columns = grid.reduce((acc, row) => {
// First pass, create 9 empty arrays
if (acc.length === 0) {
for (let i = 0; i < 9; i++) {
acc.push([])
}
}
// For each row, push each item into the array at that index
row.forEach((r, index) => {
acc[index].push(r)
})
return acc
}, [])
return columns.map(col => validatePart(col)).reduce(reduceBools, true)
}
function validateCells (grid) {
const cells = grid.reduce((gridAcc, row, gridIndex) => {
// First pass, create 9 empty arrays
if (gridAcc.length === 0) {
for (let i = 0; i < 9; i++) {
gridAcc.push([])
}
}
const rowWithGroups = row.reduce((acc, cur, rowIndex) => {
if (rowIndex < 3) {
acc[0].push(cur)
} else if (rowIndex < 6) {
acc[1].push(cur)
} else {
acc[2].push(cur)
}
return acc
}, [[], [], []])
if (gridIndex < 3) {
rowWithGroups.forEach((group, groupIndex) => {
gridAcc[groupIndex] = [ ...gridAcc[groupIndex], ...group ]
})
} else if (gridIndex < 6) {
rowWithGroups.forEach((group, groupIndex) => {
gridAcc[groupIndex + 3] = [ ...gridAcc[groupIndex + 3], ...group ]
})
} else {
rowWithGroups.forEach((group, groupIndex) => {
gridAcc[groupIndex + 6] = [ ...gridAcc[groupIndex + 6], ...group ]
})
}
return gridAcc
}, [])
return cells.map(cell => validatePart(cell)).reduce(reduceBools, true)
}
function validatePart (array) {
const noDots = array.filter(i => i !== '.')
const uniqItems = noDots.reduce((acc, cur) => {
const index = acc.findIndex(item => item === cur)
if (index === -1) {
acc.push(cur)
}
return acc
}, [])
return uniqItems.length === noDots.length
}
function reduceBools (state, bool) {
if (!bool) {
state = false
}
return state
}
console.log(validateSudoku(grid)) // true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment