This commit is contained in:
StevanFreeborn
2022-05-27 12:28:02 -05:00
parent 49fb66463a
commit 544ebfe78b
6 changed files with 231 additions and 34 deletions
+4
View File
@@ -18,5 +18,9 @@ export const puzzlesAndSolutions = [
[ [
'82..4..6...16..89...98315.749.157.............53..4...96.415..81..7632..3...28.51', '82..4..6...16..89...98315.749.157.............53..4...96.415..81..7632..3...28.51',
'827549163531672894649831527496157382218396475753284916962415738185763249374928651' '827549163531672894649831527496157382218396475753284916962415738185763249374928651'
],
[
// unsolvable
'9.9..5.1.85.4....2432......1...69.83.9.....6.62.71...9......1945....4.37.4.3..6..'
] ]
]; ];
+27 -8
View File
@@ -1,5 +1,3 @@
import { columns } from '../models/columns';
import { rows } from '../models/rows';
import { grids } from '../models/grids'; import { grids } from '../models/grids';
class SudokuSolver { class SudokuSolver {
@@ -16,6 +14,18 @@ class SudokuSolver {
checkRowPlacement(puzzleString, row, column, value) { checkRowPlacement(puzzleString, row, column, value) {
const rows = {
A: [],
B: [],
C: [],
D: [],
E: [],
F: [],
G: [],
H: [],
I: [],
};
// rowKeys // rowKeys
const rowKeys = Object.keys(rows); const rowKeys = Object.keys(rows);
@@ -45,8 +55,20 @@ class SudokuSolver {
checkColPlacement(puzzleString, row, column, value) { checkColPlacement(puzzleString, row, column, value) {
const columnKeys = Object.keys(columns); const columns = {
1: [],
2: [],
3: [],
4: [],
5: [],
6: [],
7: [],
8: [],
9: [],
};
const columnKeys = Object.keys(columns);
columnKeys.forEach((key, i) => { columnKeys.forEach((key, i) => {
let values = [] let values = []
@@ -58,12 +80,9 @@ class SudokuSolver {
const columnValue = puzzleString.slice(start, end); const columnValue = puzzleString.slice(start, end);
values.push(columnValue); columns[n].push(columnValue);
}); });
columns[key] = values;
}); });
// get column values for placement // get column values for placement
@@ -103,7 +122,7 @@ class SudokuSolver {
default: default:
break; break;
} }
// make sure placement location doesn't contain a value and column doesn't contain value // make sure placement location doesn't contain a value and column doesn't contain value
// or location already contains value // or location already contains value
return (existingValue == '.' && !columnValues.includes(value)) || existingValue == value; return (existingValue == '.' && !columnValues.includes(value)) || existingValue == value;
-11
View File
@@ -1,11 +0,0 @@
export const columns = {
1: [],
2: [],
3: [],
4: [],
5: [],
6: [],
7: [],
8: [],
9: [],
};
-11
View File
@@ -1,11 +0,0 @@
export const rows = {
A: [],
B: [],
C: [],
D: [],
E: [],
F: [],
G: [],
H: [],
I: [],
};
+2 -4
View File
@@ -1,8 +1,6 @@
'use strict'; 'use strict';
const SudokuSolver = require('../controllers/sudoku-solver'); const SudokuSolver = require('../controllers/sudoku-solver');
import { columns } from '../models/columns';
import { rows } from '../models/rows';
module.exports = function (app) { module.exports = function (app) {
@@ -31,8 +29,8 @@ module.exports = function (app) {
const col = coordinate.slice(1, coordinate.length); const col = coordinate.slice(1, coordinate.length);
// get the valid rows and cols // get the valid rows and cols
const validRows = Object.keys(rows); const validRows = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
const validColumns = Object.keys(columns); const validColumns = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
// if the passed row or col value are not valid return error. // if the passed row or col value are not valid return error.
if (!validRows.includes(row) || !validColumns.includes(col)) return res.status(200).json({error: 'Invalid coordinate'}); if (!validRows.includes(row) || !validColumns.includes(col)) return res.status(200).json({error: 'Invalid coordinate'});
+198
View File
@@ -2,9 +2,207 @@ const chai = require("chai");
const chaiHttp = require('chai-http'); const chaiHttp = require('chai-http');
const assert = chai.assert; const assert = chai.assert;
const server = require('../server'); const server = require('../server');
const { puzzlesAndSolutions } = require('../controllers/puzzle-strings');
chai.use(chaiHttp); chai.use(chaiHttp);
suite('Functional Tests', () => { suite('Functional Tests', () => {
test('POST /api/solve Solve a puzzle with valid puzzle string', (done) => {
const puzzleString = puzzlesAndSolutions[0][0];
const solution = puzzlesAndSolutions[0][1];
chai.request(server)
.post('/api/solve')
.set('content-type', 'application/x-www-urlencoded')
.type('form')
.send(`puzzle=${puzzleString}`)
.end((err, res) => {
if (err) console.log(err);
assert.equal(res.status, 200);
assert.isObject(res.body);
assert.propertyVal(res.body, 'solution', solution);
done();
});
});
test('POST /api/solve Solve a puzzle with missing puzzle string', (done) => {
chai.request(server)
.post('/api/solve')
.set('content-type', 'application/x-www-urlencoded')
.type('form')
.end((err, res) => {
if (err) console.log(err);
assert.equal(res.status, 200);
assert.isObject(res.body);
assert.propertyVal(res.body, 'error', 'Required field missing');
done();
});
});
test('POST /api/solve Solve a puzzle with invalid characters', (done) => {
const puzzleString = puzzlesAndSolutions[0][0].slice(0,80) + '?';
chai.request(server)
.post('/api/solve')
.set('content-type', 'application/x-www-urlencoded')
.type('form')
.send(`puzzle=${puzzleString}`)
.end((err, res) => {
if (err) console.log(err);
assert.equal(res.status, 200);
assert.isObject(res.body);
assert.propertyVal(res.body, 'error', 'Invalid characters in puzzle');
done();
});
});
test('POST /api/solve Solve a puzzle with incorrect length', (done) => {
const puzzleString = puzzlesAndSolutions[0][0] + '.';
chai.request(server)
.post('/api/solve')
.set('content-type', 'application/x-www-urlencoded')
.type('form')
.send(`puzzle=${puzzleString}`)
.end((err, res) => {
if (err) console.log(err);
assert.equal(res.status, 200);
assert.isObject(res.body);
assert.propertyVal(res.body, 'error', 'Expected puzzle to be 81 characters long');
done();
});
});
test('POST /api/solve Solve a puzzle that cannot be solved', (done) => {
const puzzleString = puzzlesAndSolutions[5][0]
chai.request(server)
.post('/api/solve')
.set('content-type', 'application/x-www-urlencoded')
.type('form')
.send(`puzzle=${puzzleString}`)
.end((err, res) => {
if (err) console.log(err);
assert.equal(res.status, 200);
assert.isObject(res.body);
assert.propertyVal(res.body, 'error', 'Puzzle cannot be solved');
done();
});
});
test('POST /api/check Check a puzzle placement with all fields', (done) => {
const puzzleString = puzzlesAndSolutions[0][0];
const coordinate = 'A2';
const value = '3';
chai.request(server)
.post('/api/check')
.set('content-type', 'application/x-www-urlencoded')
.type('form')
.send(`puzzle=${puzzleString}`)
.send(`coordinate=${coordinate}`)
.send(`value=${value}`)
.end((err, res) => {
if (err) console.log(err);
assert.equal(res.status, 200);
assert.isObject(res.body);
assert.propertyVal(res.body, 'valid', true);
done();
});
});
test('POST /api/check Check a puzzle placement with single placement conflict', (done) => {
assert.fail();
done();
});
test('POST /api/check Check a puzzle placement with multiple placement conflicts', (done) => {
assert.fail();
done();
});
test('POST /api/check Check a puzzle placement with all placement conflicts', (done) => {
assert.fail();
done();
});
test('POST /api/check Check a puzzle placement with missing required fields', (done) => {
assert.fail();
done();
});
test('POST /api/check Check a puzzle placement with invalid characters', (done) => {
assert.fail();
done();
});
test('POST /api/check Check a puzzle placement with incorrect length', (done) => {
assert.fail();
done();
});
test('POST /api/check Check a puzzle placement with invalid placement coordinate', (done) => {
assert.fail();
done();
});
test('POST /api/check Check a puzzle placement with invalid placement value', (done) => {
assert.fail();
done();
});
}); });