javascriptarraysfunctionsudoku

Sudoku Validator is not returning correct boolean


I'm writing a sudoku validator and I've run into a problem at the very end of it. I'm very new to coding, so please be patient with me. The function sudokuIsValid is supposed to take a puzzle (an array of 9 arrays) and check each column, row, and 3x3 grid to see if it is valid. The function includes1To9 works on its own, getColumn works, getRow works, and getSection works. So from my understanding, it's just the last function sudokuIsValid. I'm not sure what is wrong with it, probably something minute. I just don't know anyone else who codes, so I don't have many people to ask. I understand that this code could likely be written better. I also kindly ask you do not try to introduce me to new operators or things like that.. May you please just explain why this does not work? I don't understand why sudokuIsValid is not returning the way it should as it is. Thanks for your help. Here's my code:

let puzzle = [[ 8,9,5,   7,4,2,   1,3,6 ],
              [ 2,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 ]];


//puzzle 2
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 ]];

//DO NOT EDIT ABOVE

function getRow(puzzle, row) {
  return puzzle[row]
};

function getColumn(puzzle, col) {
  let column = []
  for (let i = 0; i < puzzle.length; i++){
     column.push(puzzle[i][col])
}
return column
};


function getSection(puzzle, x, y) {
    x *= 3 
    y *= 3
    let cell = []
    for (let i = y; i < y + 3; i++){
       for (let j=x;j< x + 3; j++){
            cell.push(puzzle[i][j])
        
    }
}
return cell
};



function includes1To9(arr) {
    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) {
    let valid = []
    for (let i=0;i<9;i++) {
        valid.push(getRow(puzzle, i))
        valid.push(getColumn(puzzle,i))
    }
    for (let i=0;i<3;i++){
        for (let j=0; j<3; j++){
            valid.push(getSection(puzzle, i, j))
        }
    }

    for (let i=0; i < valid.length; i++) {
        if (includes1To9(valid[i]) === false){
            return false
        } else {
            return true
            }
        }

};
        
console.log(sudokuIsValid(puzzleTwo)) // returns true. But should return false because the first column has two 8's.
console.log(includes1To9([8,8,4,9,5,6,1,7,3])) // returns false, works as it should. This is also the first column of puzzleTwo which should make sudokuIsValid return false.

Solution

  • This is due to a small logic error in your code, the final for loop in the sudokuIsValid is wrong specificaly

    if (includes1To9(valid[i]) === false){
            return false
        } else {
            return true
        }
    }
    
    

    Your returning true whenever a single row or column, section has all the numbers

    change the last for to:

    for (let i=0; i < valid.length; i++) {
        if (includes1To9(valid[i]) === false){
            return false
        }
    }
    return true
    

    and it worked for me