Skip to content

Instantly share code, notes, and snippets.

@Lumexralph
Last active September 28, 2020 13:34
Show Gist options
  • Save Lumexralph/8705843450b31f75f727316956747d8b to your computer and use it in GitHub Desktop.
Save Lumexralph/8705843450b31f75f727316956747d8b to your computer and use it in GitHub Desktop.
Write a sudoku validator: // 1. The `solution_valid(board)` function should return True when the // solution is True, False otherwise. The cells of the sudoku board may // also contain 0's, which represent empty cells. Boards with empty cells // are invalid of course. For the standard rules see // https://en.wikipedia.org/wiki/Sudoku // 2. Divid…
// SETUP! DO NOT TOUCH!
const Mocha = require('mocha')
const chai = require('chai')
const { expect } = chai
const mocha = new Mocha()
mocha.suite.emit('pre-require', this, 'solution', mocha)
// END OF SETUP
// ===========================================================================
// PUZZLE 2
// Write a sudoku validator:
// 1. The `solution_valid(board)` function should return True when the
// solution is True, False otherwise. The cells of the sudoku board may
// also contain 0's, which represent empty cells. Boards with empty cells
// are invalid of course. For the standard rules see
// https://en.wikipedia.org/wiki/Sudoku
// 2. Divide the problem into subproblems, write separate functions for
// these.
// 3. Make sure to write some tests for these functions.
const rowCheck = (board) => {
if (board.length === 0) return false;
for (let row = 0; row < board.length; row += 1) {
if (board[row].length === 0) return false;
const uniqueRow = new Set(board[row]);
if (uniqueRow.size !== board[row].length) return false;
}
return true;
};
const checkUniqueCol = (col) => {
const uniqueCol = new Set(col);
return uniqueCol.size === col.length;
};
const colCheck = (board) => {
if (board.length === 0) return false;
let unique = false;
let colIndex = 0;
let rowIndex = 0;
let col = [];
while (colIndex < board.length) {
if (rowIndex >= board.length) {
// do a unique column check, reset rowIndex
// move to next column and empty the initial col
if (checkUniqueCol(col) === false) return false;
rowIndex = 0;
colIndex += 1;
col = [];
}
if (board[rowIndex].length === 0) return false;
col.push(board[rowIndex][colIndex]);
rowIndex += 1;
}
return true;
};
const generateSubGridMap = (boardLength) => {
const subGridMap = {};
for (let row = 0; row < boardLength; row += 1) {
const gridLabel = `subGrid${row+1}`;
if (subGridMap.gridLabel === undefined) {
subGridMap[gridLabel] = [];
}
}
return subGridMap;
};
const fillSubGridMap = (board, subGridMap) => {
for (let row = 0; row < board.length; row += 1) {
if (row < 3) {
subGridMap.subGrid1 = [...subGridMap.subGrid1, ...board[row].slice(0, 3)];
subGridMap.subGrid2 = [...subGridMap.subGrid2, ...board[row].slice(3, 6)];
subGridMap.subGrid3 = [...subGridMap.subGrid3, ...board[row].slice(6, 9)];
} else if (row < 6) {
subGridMap.subGrid4 = [...subGridMap.subGrid4, ...board[row].slice(0, 3)];
subGridMap.subGrid5 = [...subGridMap.subGrid5, ...board[row].slice(3, 6)];
subGridMap.subGrid6 = [...subGridMap.subGrid6, ...board[row].slice(6, 9)];
} else {
subGridMap.subGrid7 = [...subGridMap.subGrid7, ...board[row].slice(0, 3)];
subGridMap.subGrid8 = [...subGridMap.subGrid8, ...board[row].slice(3, 6)];
subGridMap.subGrid9 = [...subGridMap.subGrid9, ...board[row].slice(6, 9)];
}
}
return subGridMap;
};
const checkSubGrid = (board) => {
const subGridMap = generateSubGridMap(board.length);
const filledSubGridMap = fillSubGridMap(board, subGridMap);
// check all the generated subGrids
for (const subGrid in filledSubGridMap) {
if (checkUniqueCol(subGridMap[subGrid]) === false) return false;
}
return true;
}
const validateSudoku = (board) => {
// Your solution
return colCheck(board) && rowCheck(board) && checkSubGrid(board)
}
// TESTS PUZZLE 2
describe('Sudoku', () => {
it('should return true for a valid solution', () => {
const board = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9],
]
expect(validateSudoku(board)).to.equal(true)
})
it('should return false when there are empty fields', () => {
const board = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 0, 3, 4, 9],
[1, 0, 0, 3, 4, 2, 5, 6, 0],
[8, 5, 9, 7, 6, 1, 0, 2, 0],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 0, 1, 5, 3, 7, 2, 1, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 0, 0, 4, 8, 1, 1, 7, 9],
]
expect(validateSudoku(board)).to.equal(false)
})
it('should return false when a column is invalid', () => {
const board = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 5, 8, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9],
]
expect(validateSudoku(board)).to.equal(false)
})
it('should return false when a row is invalid', () => {
const board = [
[5, 3, 4, 8, 7, 6, 9, 1, 2],
[8, 7, 2, 1, 9, 5, 3, 4, 6],
[1, 9, 6, 3, 4, 2, 5, 8, 7],
[6, 4, 9, 7, 8, 1, 5, 2, 3],
[4, 2, 8, 6, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 6, 5, 8],
[9, 8, 1, 5, 3, 7, 2, 6, 4],
[2, 6, 7, 4, 1, 9, 8, 3, 5],
[3, 4, 5, 2, 6, 8, 1, 7, 9],
]
expect(validateSudoku(board)).to.equal(false)
})
it('should return false when a block is invalid', () => {
const board = [
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[2, 3, 4, 5, 6, 7, 8, 9, 1],
[3, 4, 5, 6, 7, 8, 9, 1, 2],
[4, 5, 6, 7, 8, 9, 1, 2, 3],
[5, 6, 7, 8, 9, 1, 2, 3, 4],
[6, 7, 8, 9, 1, 2, 3, 4, 5],
[7, 8, 9, 1, 2, 3, 4, 5, 6],
[8, 9, 1, 2, 3, 4, 5, 6, 7],
[9, 1, 2, 3, 4, 5, 6, 7, 8],
]
expect(validateSudoku(board)).to.equal(false)
})
})
describe('rowCheck', () => {
it('should return true for a valid row', () => {
const board = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
]
expect(rowCheck(board)).to.equal(true)
})
it('should return false when there are empty blocks', () => {
const board = [];
expect(rowCheck(board)).to.equal(false)
})
it('should return false when there are empty sub blocks', () => {
const board = [[], []];
expect(rowCheck(board)).to.equal(false)
})
it('should return false for a invalid row check', () => {
const board = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 8, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 5, 8, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 4, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9],
];
expect(rowCheck(board)).to.equal(false)
})
})
describe('colCheck', () => {
it('should return true for a valid column', () => {
const board = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 8, 5, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9],
];
expect(colCheck(board)).to.equal(true);
})
it('should return false when there are empty blocks', () => {
const board = [];
expect(colCheck(board)).to.equal(false)
})
it('should return false when there are empty sub blocks', () => {
const board = [[], []];
expect(colCheck(board)).to.equal(false)
})
it('should return false for a invalid column check', () => {
const board = [
[5, 3, 4, 6, 7, 8, 9, 1, 2],
[6, 7, 2, 1, 9, 5, 3, 4, 8],
[1, 9, 8, 3, 4, 2, 5, 6, 7],
[8, 5, 9, 7, 6, 1, 4, 2, 3],
[4, 2, 6, 8, 5, 3, 7, 9, 1],
[7, 1, 3, 9, 2, 4, 5, 8, 6],
[9, 6, 1, 5, 3, 7, 2, 8, 4],
[2, 8, 7, 4, 1, 9, 6, 3, 5],
[3, 4, 5, 2, 8, 6, 1, 7, 9],
];
expect(colCheck(board)).to.equal(false)
})
})
mocha.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment