Cita:
Iniciado por amchacon .................................................. .............................
Ya que se comenta el tema, estos sudokus los has generado con un programa tuyo. ¿Que estrategia has usado para que sea 100% aleatorio? ^^
Antes que nada, gracias por el código que me pasaste, muy interesante y me ha animado a hacer otro con el mismo objetivo.
Bueno, como han pasado ya unos días no creo que se considere hacer la tarea y sí compartir con un amigo y el resto del foro una idea, aún incipiente, pero funcional.
Pues bien
amchacon, la idea en sí es más sencilla de explicar que de ponerla en práctica. Para fijar ideas me referiré a un Sudoku de 9x9 casillas lo que equivale a tres casillas de 9x9 en cada una de las tres líneas, aunque el program que propongo genera Sudokus más variados como de 2x2, 2x3, 2x4, 3x2, 3x3, 3x4, 3x5 ,4x4, 4x5 ,4x6 y así ....excepto el de 5x5 y mayores. Aún lo tengo en fase alfa y tengo que "dirigir" los aleatorios para que sea más eficiente y alcance tamaños mayores. Pero no te quería hacer esperar más.
* Existen dos índices o contadores, uno parcial y otro total, que me indica si tengo que hacer un reinicio parcial o total si se bloquea el relleno, vamos si no encuentra números válidos para rellenar alguna casilla.
* Se trata de ir rellenando casilla a casilla, es decir que no se rellena como una matriz normal línea a línea sino que se rellenan casilla a casilla de 3x3 en cada línea. Parece una tontería pero el que recorra tres columnas, baje para rellenar otras tres y vuelva a la primera línea otra vez para ir rellanando otra casilla tiene su miga.
* La forma de relleno es casi obvia. Por cada casilla que relleno genero un conjunto de valores aleatorios del 1 al 9 y de forma aleatoria los voy metiendo en la casilla correspondiente y voy poniendo los valores del array a cero y eso me indica que si sale un aleatorio y el array vale cero tendía que coger otro porque ese ya está pillado.
* Y el meollo del problema: que no se repitan en más de una línea y columna. De eso se encarga el array "ocupados" donde voy guardando los valores que han salido para no repetirlos. Es muy "jugoso" ya que además de tener las dimensiones del tamaño del Sudoku, [tam][tam] incorpora otras dos dimensiones, resultando en un
¡¡¡ array cuadrimensiona ¡¡¡. La tercera dimensión, [salto] la uso para una pequeña "virguería". Y es que si se supera el contador total el reinicio es desde cero, se vuelve al estado original, pero si el contador que se supera es el parcial el reinicio sólo afecta al "salto" ( en este caso de 3x3 hay tres saltos correspondientes a conjuntos de tres líneas por cada salto ). Por ejemplo si estoy en el salto 3 ( líneas de 6 a 9 ) y se hace un reinicio parcial los otros dos saltos anteriores ( líneas de 1 a 6 ) conservan sus valores y se sigue intentando rellenar sólo el tercer salto, así me ahorro reinicios innecesarios. Y es que me manejo muy bien con arrays multidimensionales y casi siempre puedo prescindir de cosas como estructuras, listas y árboles, al fin y al cabo no dejan de ser arrays manejados de forma implícita.
Pero te comento que ha sido algo rapidito y está muy verde aún, aunque insisto en que es totalmente funcional. Y como era algo para salir del paso y ver si podía superar el reto de conseguirlo, no he dudado en usar cosas como el goto. Ya en versiones posteriores lo eliminaré, son cosas de mis inicios hace más de cuatro décadas en Basic y Fortran
.
Por cierto, te dejo activado un printf para que veas que está en ejecución. Hay otra línea con un "imprimir" que la puedes activar para "ver" como se rellena el Sudoku. También están desactivados unos arrays que hacen las veces de los contadores y es que estoy haciendo pruebas para encontrar unos valore óptimos de los mencionados contadores, aunque se compica porque a su vez están relacionados con el tamaño de la matriz. Pero todo se andará .........
El código que te paso en primer lugar es el "humanizado", vamos el que uso para compartir códigos y que se entienda meridianamente bien. El segundo te lo dejo como curiosidad para que veas como trabajo en modo "borrador". Como observarás es muy "compacto", con for muy largos e if sin cuerpo que acaban en punto y coma. Y es que como hábito y para concentrarme en lo básico, el algoritmo que resuelva un problema, paso de perder tiempo en pequeñeces, así entenderás mejor el uso intensivo que hago del operador condicional. Estoy tan acostumbrado al mismo que no me cuesta nada encadenarlos, pero todo es cuestión de práctica, sencillamente.
. De paso te dejo una salida de uno de 4x4 y, por cierto, los de 3x3 tardan menos de un segundo, no así los de 4x4 que va de unos pocos segundos a un minuto y es que rellenar de esa forma aleatorio una matriz de 256 elementos es tela marinera:
Sigue en el siguiente mensaje..................no cabe en uno sólo
.
¡¡¡Saluditos!!!