Intentar escribir un guión que verifique si el Sudoku se resuelve correctamente. Traté de verificar cada valor usando 2 ciclos y el método de prueba y reemplacé el valor a "0" si la prueba devuelve verdadero pero el script no reemplaza todos los valores y no entiendo por qué. ¿Podría explicar por qué el script reemplaza algunos valores, pero otros no?
const doneOrNot = (sudoku) => { const copiedSudoku = JSON.parse(JSON.stringify(sudoku)); console.log(copiedSudoku); const testNums = [1, 2, 3, 4, 5, 6, 7, 8, 9]; for (const num in copiedSudoku) { for (const newnum in copiedSudoku[num]) { const regexp = RegExp(`${testNums[newnum]}`); if (regexp.test(copiedSudoku[num])) { copiedSudoku[num][newnum] = 0; } } } return copiedSudoku; }; console.log(doneOrNot( [[5, 3, 4, 6, 7, 8, 9, 1, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 7, 9, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 1, 7, 9]], ));pero el script no reemplaza todos los valores y no entiendo por qué.
Eso sucede porque su código busca el número de columna como un valor en la fila actual, pero es posible que ese valor ya se haya cambiado a 0, por lo que no hay coincidencia y el valor actual no será reemplazado por 0.
En su ejemplo, esto sucede en la primera fila, cuando el ciclo interno está en su tercera iteración. Entonces newnum es igual a 2, momento en el cual la fila de sudoku actual copiedSudoku[num] se ve así:
[0, 0, 4, 6, 7, 8, 9, 1, 2] Como puede ver, las dos iteraciones anteriores del ciclo interno colocaron un cero, pero ahora testNums[newnum] es 3, y ese número ya se borró, por lo que la llamada al método de test devolverá falso, por lo que 4 no se borrará.
El comentario principal sobre este algoritmo es que no debería ser necesario modificar nada en el Sudoku dado. El algoritmo solo debe mirar y calcular.
Es excesivo crear una expresión regular solo para encontrar un dígito. Para eso, puede usar el método de matriz de include .
El método .test RegExp espera una cadena como argumento, pero le pasa una matriz. Esto significa que la matriz se convierte en una cadena separada por comas, por lo que todavía funciona, pero ciertamente no se recomienda.
No es una buena práctica usar un bucle for..in sobre una matriz . Si está interesado en los valores de la matriz, use un bucle for..of .
Como el nombre de su función sugiere un valor de retorno booleano, no debería devolver el Sudoku, sino indicar el éxito con verdadero o falso.
Como se dijo, no debería haber necesidad de colocar ceros. No ayuda a alcanzar su meta.
const hasAllDigits = arr => arr.reduce((acc, digit) => acc | (1 << digit), 0) == 0x3FE; const doneOrNot = (sudoku) => { for (let i = 0; i < 9; i+=3) { for (let j = 0; j < 3; j++) { let k = i + j; // Check k-th row if (!hasAllDigits(sudoku[k])) return false; // Check k-th column if (!hasAllDigits(sudoku.map(row => row[k]))) return false; // Check k-th 3x3 box if (!hasAllDigits(sudoku.slice(j*3, j*3+3) .flatMap(row => row.slice(i, i + 3)))) return false; } } return true; }; console.log(doneOrNot( [[5, 3, 4, 6, 7, 8, 9, 1, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 7, 9, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 1, 7, 9]], ));