skip to Main Content

I know people dont like homework questions however,i have been working on this too long now over 6 hours, and am out of ideas, and for some reason my sudoku validator keeps returning the wrong boolean, it has to be the sudokuisvalid part, but i have no clue why it wont return the correct boolean now

rewrote the code but unfortunately i dont know anyother way to go about that part, still nothing, i rechecked all the other parts, checked getRow, works perfectly, checked getColumn, works perfectly, checked getSection, works perfectly, checked includes1To9, also works perfectly its something in the sudokuIsValid part but I can not figure out what is wrong with it, it seems like it accesses getRow, getColumn, getSection, and the incudes1To9 fine, and it displays a boolean but only says true…

tried to do as something based off of what someone said here, it is still doing that true when supposed to be false thing.

Error: sudokuIsValid returns true for valid sample puzzle (the variable puzzle)
Error 2: sudokuIsValid returns true for other valid puzzles not provided in the problem

im really hoping its something obvious and im just too tired, and im new to programming so ill paste my code and see what y’all think!

I tried to make what i believe is the problem area in bold which just put asterisk around it

function getRow(puzzle, row) {
// WRITE YOUR CODE HERE
return puzzle[row]
}

function getColumn(puzzle, col) {
// WRITE YOUR CODE HERE
return puzzle.map(row=>row[col])
}

function getSection(puzzle, x, y) {
// WRITE YOUR CODE HERE
let section = []
for(i = 3 * y; i < 3 * y + 3; i++){
  for(j = 3 * x; j < 3*x+3 ; j++){
    section.push(puzzle[i][j])
  }
}
return section
}

function includes1To9(arr) {
// WRITE YOUR CODE HERE
  for (i = 0; i < arr.length; i++){
    for (j = 0; j < arr.length; j++){
      if (j != i){
        if (arr[i] === arr[j]){
          return false
        }
      }
    }
  }
  return true
}

function sudokuIsValid(puzzle) {
  for (let i = 0; i < 9; i++){
    if(includes1To9(getRow) === false){
      return false
    }
  }
  for (let i= 0; i < 9; i++){
    if(includes1To9(getColumn) === false){
      return false
    }
  }
  for(let i = 0; i < 3; i++){
    for(let j =0; j < 3; j++){
      if(includes1To9(getSection) === false){
        return false
      }
    }
  }
  return true
}

// example of the puzzle that is being input and returning true, should return false

let puzzleTwo = [[ 8,9,5,  7,4,2,  1,3,6 ],
                 [ 8,7,1,  9,6,3,  4,8,5 ],
                 [ 4,6,3,  5,8,1,  7,9,2 ],

                 [ 9,3,4,  6,1,7,  2,5,8 ],
                 [ 5,1,7,  2,3,8,  9,6,4 ],
                 [ 6,8,2,  4,5,9,  3,7,1 ],

                 [ 1,5,9,  8,7,4,  6,2,3 ],
                 [ 7,4,6,  3,2,5,  8,1,9 ],
                 [ 3,2,8,  1,9,6,  5,4,7 ]];

console.log(sudokuIsValid(puzzleTwo)) // returns true should be false
console.log(includes1To9([8,8,4,9,5,6,1,7,3])) // returns false like it should

2

Answers


  1. How to improve your code and solve your problem:

    • You don’t need to have a list of valid. You can check every possibility and if the function returns false then you can immediately return false. At the end of the function you can do return true. this will solve your problem since in your includes1to9 you check all the rows, columns and subgrids. that means you check if there are numbers through 1 to 9 in the entire puzzle and if you find two of the same items, then you exit. so for example if you have a sudoku puzzle like this:
      900 000 000
      000 000 000
      000 000 000

      000 000 000
      000 000 000
      000 000 000

      000 000 000
      000 000 000
      000 000 009
      it will return true cause (if we don’t check zeros) there are two nines in the puzzle. 2 nines in two rows, 2 nines in two columns, 2 nines in two subgrids = 6 nines…

    • Note: – use Sets (if you learned them). They cannot contain duplicate items, eg. if you have an array that is 0, 1, 2, 2, 2, 5, 6, 7, 8, 9 (duplicate 2s), then it will give you 0, 1, 2, 5, 6, 7, 8, 9. You can then compare the array to the set and see if they are similiar size. You can use your double-for loop. while it is fine, Sets will simplify your code. if you haven’t learned about Sets or you don’t understand them, then don’t use them.

    So from these, your code should look like this:

    
    function SudokuIsValid(sudoku){
      for row {
        if (row is not valid){
          return false
          // return false exits/stops the function. 
          // No code after this will be run in this function.
        }
      }
      // if code has gotten here, that means that all rows are valid.
      for column {
        if (column is not valid){
          return false
        }
      }
      // if code has gotten here, that means all columns are valid
      for subgrid {
        if (subgrid is not valid){
          return false
        }
      }
      // if code has gotten here, that means all rows, columns and subgrids are valid.
      // we can return true then
      return true
    }
    
    Login or Signup to reply.
  2. As explained in the comments, there are some issue in how you approached the problem: as you wrote it, getSection() returns an array and you push it into valid which itself is an array containing already the values inside puzzle, since getRow() and getColumn() are pushed into it before pushing in getSection().

    Here it is my approach following your code as a base, I strongly suggest you to take and see what are the differences between said approach and yours. You can take inspiration from this code to try recreate your own as an exercise.

    function getRow(puzzle, row)  {return puzzle[row]};
    function getColumn(puzzle, col) {return puzzle.map(row => row[col])};
    
    function getSection(puzzle, x, y) {
      // Initializing the section matrix
      let section = [[],[],[]];
      for(i = 3 * x; i < 3 * x + 3; i++){
        for(j = 3 * y; j < 3*y+3 ; j++){
          // Pushing into the matrix 3x3 each element (0 % 3 == 0, 3 % 0 == 0, etc...)
          section[i%3].push(puzzle[i][j]);
        }
      }
      return section;
    };
    
    function arrayIncludes1To9(arr) {
      for (let i = 1; i < 10; i++)  {
        // If i is not in the array return false
        if (!arr.includes(i))  {
          return false;
        }
      }
      // True otherwise
      return true;
    }
    function sectionIncludes1To9(matr)  {
      let arr = [];
      // Getting each matrix as an array to reutilize arrayIncludes1To9()
      matr.forEach(element => {
        element.map(x => arr.push(x));
      });
      return arrayIncludes1To9(arr);
    }
    
    function sudokuIsValid(puzzle) {
      let columns = [];
      let rows = [];
      // Assuming all the sections are correct
      let sections = true;
    
      for (let i = 0; i < 10; i++)  {
        columns.push(getColumn(puzzle, i));
        rows.push(getRow(puzzle, i));
      }
      // Cycling through each section until one is not valid
      for (let i = 0; i < 3 && sections; i++) {
        for (let j = 0; j < 3 && sections; j++) {
          if (!sectionIncludes1To9(getSection(puzzle, i, j))) {
            sections = false;
          }
        }
      }
      // Returning true if columns, rows and sections are valid; false otherwise
      return arrayIncludes1To9(columns) && arrayIncludes1To9(rows) && sections;
    }
    
    
    
    let puzzleTwo = [[ 8,9,5,  7,4,2,  1,3,6 ],
                     [ 8,7,1,  9,6,3,  4,8,5 ],
                     [ 4,6,3,  5,8,1,  7,9,2 ],
    
                     [ 9,3,4,  6,1,7,  2,5,8 ],
                     [ 5,1,7,  2,3,8,  9,6,4 ],
                     [ 6,8,2,  4,5,9,  3,7,1 ],
    
                     [ 1,5,9,  8,7,4,  6,2,3 ],
                     [ 7,4,6,  3,2,5,  8,1,9 ],
                     [ 3,2,8,  1,9,6,  5,4,7 ]];
    
    console.log(sudokuIsValid(puzzleTwo)); // false
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search