3
\$\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>

\$\endgroup\$
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>

\$\endgroup\$
  • 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\$ – mdfst13 Apr 4 '16 at 18:24
  • \$\begingroup\$ hey, thx for the response. I'll update the answer. \$\endgroup\$ – rafaelcastrocouto Apr 4 '16 at 22:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.