2
\$\begingroup\$

I decided to learn JavaScript and what better way than wrestling with a Sudoku solver. I'm guessing there are (many?) optimizations that I missed. I'm thinking of adding a generator also, but this for another time. Thoughts?

<!DOCTYPE html>
<head>
 <title></title>
</head>
<body>
 <form action="" method="post" accept-charset="utf-8" name="form">
 <table>
 <thead>
 <tr>
 <th></th>
 </tr>
 </thead>
 <tbody>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 <tr>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 <td>
 <input type="text" size="1" name="sud[]"></input>
 </td>
 </tr>
 </tbody>
 </table>
 <button type="button" size="2" onclick="test();">Solve</button>
 </form>
 <script>
 function solve(matrix) {
 for (var i = 0; i <= 8; i++) {
 for (var j = 0; j <= 8; j++) {
 //check for legitimate values
 if (matrix[i][j] != 0) {
 continue;
 }
 for (var k = 1; k <= 9; k++) {
 if (insert(matrix, i, j, k) == true) {
 matrix[i][j] = k;
 b = solve(matrix);
 if (b == true) {
 return true;
 }
 matrix[i][j] = 0;
 }
 }
 return false;
 }
 }
 return true;
 }
 function insert(matrix, i, j, k)
 //check column and rows
 {
 for (var a = 0; a <= 8; a++) {
 if (a != i && matrix[a][j] == k) {
 return false;
 }
 }
 for (var a = 0; a <= 8; a++) {
 if (a != j && matrix[i][a] == k) {
 return false;
 }
 }
 //check the 3 by 3 squares
 var y = Math.floor((i / 3)) * 3;
 var x = Math.floor((j / 3)) * 3;
 for (var a = 0; a < 3; a++) {
 for (var b = 0; b < 3; b++) {
 if (a != i && b != j && matrix[y + a][x + b] == k) {
 return false;
 }
 }
 }
 return true;
 }
 function test() {
 var holder = [];
 for (var i = 0; i < 81; i++) {
 // document.form[i].value = Math.floor(Math.random() * 9) + 1;
 //get the form values
 holder[i] = (document.form[i].value);
 var matrix = [],
 j, k;
 // from 1 dimensional to matrix
 for (j = 0, k = -1; j < holder.length; j++) {
 if (j % 9 === 0) {
 k++;
 matrix[k] = [];
 }
 matrix[k].push(holder[j]);
 }
 }
 solve(matrix);
 var solved = [];
 for (var i = 0; i < matrix.length; i++) {
 for (var j = 0; j < matrix[i].length; j++) {
 solved.push(matrix[i][j]);
 //make a one dimensional array from solved matrix;
 }
 }
 for (var z = 0; z < solved.length; z++) {
 document.form[z].value = solved[z];
 //display the solved sudoku numbers 
 }
 }
 </script>
</body>
</html>

Marc-Andre
6,7795 gold badges39 silver badges65 bronze badges
asked Apr 4, 2016 at 14:49
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Basically I used jshint and created a function to generate the table HTML content.

I also grouped the variable declarations (not "all to the top" as jslint) and simplified the conditional checks.

In the solve function, I inverted the check in order to remove the continue statement. In my opinion this makes the code easier to read (read more).

The click event is using an event listener in order to remove JS from HTML.

All DOM selection is made through query selection.

function solve(matrix) {
 var i, j, b, k;
 for (i = 0; i <= 8; i++) {
 for (j = 0; j <= 8; j++) {
 //check for legitimate values
 if (!matrix[i][j]) {
 for (k = 1; k <= 9; k++) {
 if (insert(matrix, i, j, k)) {
 matrix[i][j] = k;
 b = solve(matrix);
 if (b) { return true; }
 matrix[i][j] = 0;
 }
 }
 return false;
 }
 }
 }
 return true;
}
function insert(matrix, i, j, k) {
 //check column and rows
 var a, b;
 for (a = 0; a <= 8; a++) {
 if (a != i && matrix[a][j] == k) {
 return false;
 }
 }
 for (a = 0; a <= 8; a++) {
 if (a != j && matrix[i][a] == k) {
 return false;
 }
 }
 //check the 3 by 3 squares
 var y = Math.floor((i / 3)) * 3,
 x = Math.floor((j / 3)) * 3;
 for (a = 0; a < 3; a++) {
 for (b = 0; b < 3; b++) {
 if (a != i && b != j && matrix[y + a][x + b] == k) {
 return false;
 }
 }
 }
 return true;
}
function test() {
 var form = document.querySelector('form#sudoku'),
 matrix,
 holder = [],
 i, j, k, z;
 for (i = 0; i < 81; i++) {
 //get the form values
 holder[i] = form[i].value;
 matrix = [];
 k = -1;
 // from 1 dimensional to matrix
 for (j = 0; j < holder.length; j++) {
 if (j % 9 === 0) {
 k++;
 matrix[k] = []; 
 }
 matrix[k].push(holder[j]);
 }
 }
 solve(matrix);
 //display the solved sudoku numbers
 z = 0;
 for (i = 0; i < matrix.length; i++) {
 for (j = 0; j < matrix[i].length; j++) { 
 //display the solved sudoku numbers
 form[z].value = matrix[i][j];
 z++;
 }
 }
}
function populateTable() {
 var i, j, tr, td, input,
 table = document.querySelector('form#sudoku table'),
 tbody = document.createElement('tbody');
 table.appendChild(tbody);
 for (i = 0; i < 9; i++) {
 tr = document.createElement('tr');
 tbody.appendChild(tr);
 for (j = 0; j < 9; j++) { 
 td = document.createElement('td');
 tr.appendChild(td);
 input = document.createElement('input');
 input.type = 'text';
 input.size = 1;
 td.appendChild(input);
 }
 }
 document.querySelector('input[value=Solve]')
 .addEventListener('click', test);
}
populateTable();
<!DOCTYPE html>
<html>
 <head>
 <meta name="description" content="Sudoku">
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width">
 <title>Sudoku</title>
 </head>
 <body>
 <form id="sudoku">
 <table></table>
 <input type="button" value="Solve">
 </form>
 <!-- script src="sudoku.js" type="text/javascript" -->
 </body>
</html>

answered Apr 4, 2016 at 17:58
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hi. Welcome to Code Review! We usually prefer more review of the code. Why is the new code preferable to the old code? \$\endgroup\$ Commented Apr 4, 2016 at 18:24
  • \$\begingroup\$ hey, thx for the response. I'll update the answer. \$\endgroup\$ Commented Apr 4, 2016 at 22:51

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.