Hola,
aquí lo importante es tener claro como está compuesta una matriz.
Una matriz es en realidad una sucesion de vectores (arreglos).
Si suponemos una matriz de 3x3:
int[][] matriz = new int[3][3];
Esto en realidad es una agrupacion de 3 vectores, en los que cada vector tiene a su vez 3 posiciones para guardar valores. Lo que daría un total de 9 valores posibles para guardar en la matriz.
Esto significa que yo de una matriz, puedo coger uno de esos 9 valores individuales indicando dos posiciones, la primera posicion apunta a uno de los vectores que compone la matriz y la segunda posicion apunta a uno de los valores que compone dicho vector.
Asi que con:
matriz[0][0];
Estoy apuntando al primer vector y al primer valor de dicho vector.
Con:
matriz[1][2];
Estoy apuntando al segundo vector y al tercer valor de dicho vector.
Esto seguramente ya lo tenías claro porque es lo que habitualmente se hace en programación al trabajar con matrices: apuntar a valores individuales de la matriz indicando dos posiciones.
Pero algo que quizás no sabías es que al trabajar con matrices, además de coger valores individuales, también podemos coger directamente uno de los vectores.
Asi que con:
matriz[0];
Estariamos cogiendo el primer vector al completo, con todos sus valores, de modo que podríamos tratarlo y trabajar con él como si fuera un vector (o arreglo) individual, olvidándonos de que en realidad pertenece a una matriz.
Esto no es tan habitual hacerlo al trabajar con matrices, lo de coger un vector completo... pero no es algo tan raro y de hecho para este ejercicio del Sudoku nos va a ser muy útil.
Pero antes, otra aclaración:
Muchas veces representamos la matriz como si fuera una tabla, de modo que tenemos FILAS (valores horizontales de la tabla) y COLUMNAS (valores verticales de la tabla)
Bien, pues cada FILA corresponde a un
vector completo de la matriz.
Así que como hemos dicho antes,
podemos coger fácilmente una FILA completa de la tabla/matriz y operar con ella ya que en realidad es un vector individual.
Pero en el caso de las COLUMNAS, es más complicado,
no podemos coger COLUMNAS tan fácilmente como sí podemos coger las FILAS.Los valores de las COLUMNAS se componen de valores individuales guardados en cada uno de los vectores (filas) que componen la tabla/matriz.
Así que si queremos coger los valores de una FILA, es muy fácil, le pedimos a la matriz la posicion del vector que corresponde a la FILA y ya está. Ya los tenemos estructurados dentro de un vector.
Pero si queremos coger los valores de una COLUMNA, es más dificil. Habría que recorrer cada uno de los vectores de la matriz, coger únicamente el valor individual correspondiente a la posicion de la COLUMNA que nos interesa y una vez que hemos cogido dicho valor, estructurarlo nosotros mismos en otro vector a parte donde guardaríamos todos estos valores.
¿Y por qué explico todo esto?
Un Sudoku es básicamente una tabla.
Para determinar si un Sudoku esta bien resuelto, se podría hacer cogiendo cada FILA por separado y comprobar que dicha FILA solo tiene numeros del 1 al 9 y no están repetidos.
Luego lo mismo con las COLUMNAS, ir una por una y comprobar que tienen números válidos y no repetidos
Si esto se cumple, el Sudoku es correcto.
Vale, pues esta es la lógica que tenemos que programar.
Y como ya hemos explicado, si representamos el Sudoku en forma de matriz 9x9, coger sus FILAS será muy sencillo porque son vectores individuales y la matriz nos los dará directamente indicandoles su posicion.
Pero luego coger las COLUMNAS, ya es más complicado. La matriz no nos las puede dar directamente, tendremos que recorrer cada uno de los vectores (filas), coger el valor que está en la posición de la columna y copiarlo en otro vector creado por separado para luedo poder trabajar con él.
Cada FILA y cada COLUMNA individual que obtengamos del Sudoku, tendremos que validarlas una por una comprobando que no tiene numeros repetidos.
Así que con esto, ya podemos hacernos una idea de las funciones/métodos que vamos a necesitar en nuestro código.
EL primer método que necesitaremos será uno que reciba " las líneas del Sudoku", es decir, que reciba un vector (ya provenga de una FILA o de una COLUMNA) y determine si es válida o no.
Su declaración podría ser:
boolean validarLinea(int[] linea);
Y otro método/función, que indicándole el numero de columna, sea capaz de recorrer la matriz y crear un nuevo vector con los valores correspondientes a esa columna.
Se puede declarar como:
int[] crearLineadesdeColumna(int columna);
Así obtendremos las líneas del Sudoku correspondiente a las COLUMNAS y se las podremos pasar al método
validarLinea(); que podrá trabajar con ellas igual de fácil que con las FILAS.
Pues estas son las funciones que tienes que rumiar. Si no lo consigues te ayudaremos, pero de momento intenta hacerlo tú.
Ves por partes e intenta pensar el primer método:
boolean validarLinea(int[] linea);
Este método ha de ser capaz de recorrer la linea que recibe, comprobar si tiene todos los números del 1 al 9 sin repetirse.
Si esto se cumple ha de devolver TRUE, de lo contrario ha de devolver FALSE.
Si lo consigues, ya puedes hacer la primera parte del ejercicio, que sería validar las FILAS.
Es decir, recorrer la matriz cogiendo los vectores completos y pasándoselos a la funciona validarLinea().
Y comprobar que esta funcion ha devuelto TRUE para cada uno de estos vectores/FILAS.
Si devuelve FALSE en alguno de ellos, es que el Sudoku es incorrecto.
Intentalo y luego ya se pensará como hacer la segunda parte, validar COLUMNAS.
Puedes usar esta matriz que representa un Sudoku correcto:
int[][] sudoku = {
{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}
};