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>

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

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

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.