1. LP1 - UC 1
Sudoku2TXT Pro R
Colm´an, Alberto Denis Ram´ırez, Pedro Daniel
Resumen—Implementaci´on en lenguaje C de un algoritmo de
b´usqueda de soluci´on del juego de estrategia Sudoku Samurai.
I. INTRODUCCI ´ON
Es un pasatiempo japon´es que apareci´o a mediados de los
a˜nos 80 en los diarios nipones y que en el a˜no 2005 hasta
esta ´epoca ha arrasado en los del resto del mundo. El jugador
tiene una matriz de nueve filas por nueve columnas de las
cuales algunas celdas tienen n´umeros y el resto huecos. Se
tienen que rellenar los huecos de manera que en cada fila y
columna aparezcan los n´umeros de uno al nueve sin repetirse.
As´ı de simple y as´ı de complicado. Nosotros vamos a ver, y
a implementar, un algoritmo bastante famoso: el Backtracking
o Vuelta Atr´as(haremos uso del nombre en ingl´es por ser el
de m´as uso) para solucionar Sudokus.
De alguna forma el Sudoku se basa en la b´usqueda de la
combinaci´on num´erica perfecta. Hay diferentes niveles de difi-
cultad y la resoluci´on del problema requiere paciencia y ciertas
dotes l´ogicas. Profesores de todo el mundo lo recomiendan
como m´etodo para desarrollar el razonamiento l´ogico.
II. AN ´ALISIS DEL PROBLEMA
Observe la Figura I de la tabla de 3∗3 mostrado, imag´ınese
que se dispone de 9 n´umeros(valores v´alidos en el juego) y
que s´olo uno puede estar en cada uno de la casilla, por lo
tanto en el primer tanteo todos los n´umeros son v´alidos en la
primera casilla es decir n = 9, la segunda vez s´olo son ocho
las posibles posiciones como tambi´en de n´umeros por lo tanto
n = 8.
Cuadro I
BLOQUE DE UN SUDOKU
Matem´aticamente esto se conoce como que la sucesi´on se
da en forma de factorial y como se buscan todas las posibil-
idades considerando el orden es una permutaci´on, en s´ıntesis
todas las posibilidades de “llenar” las casillas de todas las
maneras es nPn = n!, que para el caso es 9! = 362800, que
indican todas las soluciones posibles; para que este an´alisis?,
como importa el orden al buscar el llenado del sudoku queda
claro es que se necesitan muchos procesos para encontrar una
soluci´on v´alida si el m´etodo de enfrentar es el de prueba y
error, adem´as es un concepto que nos servir´a mas adelante.
Colm´an, Alberto estudiante del Departmento de Electr´onica e Inform´atica,
Universidad Cat´olica “Nuestra Se˜nora de la Asunci´on”, Asunci´on, Paraguay,
e-mail: albertocolman81@gmail.com.
Ram´ırez, Pedro estudiante del Departmento de Electr´onica e Inform´atica,
Universidad Cat´olica “Nuestra Se˜nora de la Asunci´on”, Asunci´on, Paraguay,
e-mail: pedroramirez22@gmail.com.
III. SOLUCI ´ON PROPUESTA, BACKTRACKING IMPLICA
RECURSIVIDAD
Se trata de un algoritmo de b´usqueda en el cual se explora
un ´arbol de soluciones en anchura o profundidad. Dicho de
esta manera queda muy t´ecnico as´ı que mejor vemos de
vuelta un mini − sudoku. Digamos que tenemos el siguiente
problema: se nos presenta un cuadro como el de la Figura
II , tres filas por tres columnas, donde algunas de ellas est´an
ocupadas pero otras no.
1
2
3
Cuadro II
BLOQUE DE UN SUDOKU SEMI COMPLETO
En cada hueco solo podemos poner un n´umero comprendido
entre el 1 y el 9 de tal manera que en cada fila y en cada
columna solo aparezca cada uno de estos n´umeros una vez. Por
tanto es imposible encontrar una fila que muestre un (1,3,3)
o un (2,1,1). A Donde est´a el juego? en hallar los n´umeros
que hay que poner en cada hueco de forma consecutiva de
tal manera que se verifique que cada n´umero es ´unico en su
fila y su columna. C´omo podr´ıamos elaborar un programa que
resuelva este puzzle?
Existen varias opciones, pero nos centraremos en la que
queremos ver. Comenzaremos centr´andonos en los huecos, por
tanto debemos ignorar las celdas que est´an ocupadas. Para cada
hueco tenemos que elegir un n´umero que no se encuentre ni
en su fila ni en su columna. Vamos a necesitar, por tanto, una
funci´on que escanee ambas en busca de n´umeros no usados.
Seleccionaremos uno de los posibles n´umeros y avanzare-
mos hacia la derecha rellenando los huecos hasta llegar al
´ultimo. De entre los m´etodos de resoluci´on algor´ıtmica de
problemas el m´etodo de vuelta atr´as o de backtracking
se caracteriza por plantear el mismo problema pero con la
muestra de menor tama˜no, por lo tanto, en forma recursiva.
Muchos problemas de juegos de tablero se resuelven mediante
backtracking como en este caso.
IV. CONSIDERACIONES INICIALES
Usaremos un tablero de 21 ∗ 21 e ignoraremos mediante
condicionales las celdas que no intervienen en el tablero del
sudoku, adem´as observando la Figura 1 se nota que el tablero
de 9 ∗ 9 central comparte cada uno de sus bloques de aristas
con los cuatro sudokus restantes, por lo tanto es el que tiene
mayor peso en la b´usqueda de la soluci´on.
Es decir, para minimizar el tiempo de b´usqueda primero
buscaremos la soluci´on del tablero central, una vez encontrado,
2. LP1 - UC 2
Extreme Sudoku by Sudoku2pdf Pro
Sudoku #1
1
7
5 23
7
7
4
8
2 5
6
4
9 1
1 9
2
5
9
3
2
8 8
5
6
3
2
79 5
3
1
8
3
4 7
4
8
18
3
9 5
6
7
5 2
8
1
3 9
8
9 9
3
5
2
2
7 4 3
8
7
6
7
7
3 2
2
8
4
91 4
5
9 3
23
2
6
1
8 4
9 7
1
9
7 3
3
8 5
1
8
5 3
8
9
2
2
5
6
6
6
4
9 1
83 1
6 8 9
4 8
6
2
4 9
www.sudoku9981.com
Figura 1. Planteamiento de un sudoku samurai
se verificar´a si cada uno de los tableros de 9∗9 de los extremos
tiene soluci´on, en caso de ser as´ı esto ser´ıa la soluci´on al
sudoku, no es tan f´acil como suena, pu´es de acuerdo a la
complejidad del sudoku planteado, habr´a casos donde hay que
agotar todas las soluciones posibles del sub-tablero central,
que implica? mayor tiempo de ejecuci´on, mayor consumo
de recursos y considerando que la pila stack de recursividad
podr´ıa desbordarse por sobrecarga(overhead).
Esta consideracion la hicimos para dividir el “trabajo”,
una funci´on se dedica exclusivamente a encontrar soluci´on
del sub-tablero central con las condiciones que implica al
pertenecer tambi´en a las dem´as en sus v´ertices, una vez
encontrado una de las tantas soluciones que seguro tendr´a, se
pasa la matriz modificada a la misma funci´on1
que ver´a si los
cuatro restantes sub-tableros de los extremos tienen soluci´on(al
mismo tiempo), para cada sub-tablero central encontrado, de
ser as´ı es una soluci´on2
, en caso de no ser, regresa a la
funci´on (backtracking) y vuelve a buscar otra soluci´on del
tablero central para el mismo proceso hasta agotarlo, si esto
ocurriese el sudoku no tiene soluci´on, quiz´a la tenga, s´olo
que el algoritmo no es lo bastante potente para encontrarlo,
pu´es existen algoritmos espec´ıficos para cada complejidad de
sudoku, la nuestra es la m´as general a nuestro criterio.
V. DESCRIPCI ´ON DEL ALGORITMO
Como se dijo, utilizamos una matriz de 21∗21, se definieron
cuatro zonas distintas dentro del tablero que comparten simili-
tudes que nos ayudar´an a simplificar la soluci´on del problema,
luego se consider´o la simetr´ıa que existe entre las filas y las
columnas, lo cual ayud´o m´as a la simplicidad, bueno vayamos
por pasos, primero, observe la Figura , en ´el est´an definidos
las cuatro zonas, y se hacen distinciones a cinco tableros de
sudokus simples, con las letras A,B,C,D,E.
Las zonas definidas son:
1Se tienen en cuenta condiciones distintas para los extremos
2Un sudoku bien planteado deber´ıa tener una sola soluci´on, nuestro
algoritmo busca todas las soluciones posibles.
+ + + + + + * * * x x x * * * + + + + + +
+ + + + + + * * * x x x * * * + + + + + +
+ + + + + + * * * x x x * * * + + + + + +
+ TABLERO A * x x x * TABLERO C +
+ + + + + + * * * x x x * * * + + + + + +
+ + + + + + * * * x x x * * * + + + + + +
+ + + + + + * * * o o o * * * + + + + + +
+ + + + + + * * * o o o * * * + + + + + +
+ + + + + + * * * o o o * * * + + + + + +
x x x x x x * * * o o o * * * x x x x x x
x x x x x x * TABLERO B * x x x x x x
x x x x x x * * * o o o * * * x x x x x x
+ + + + + + * * * o o o * * * + + + + + +
+ + + + + + * * * o o o * * * + + + + + +
+ + + + + + * * * o o o * * * + + + + + +
+ + + + + + * * * x x x * * * + + + + + +
+ + + + + + * * * x x x * * * + + + + + +
+ TABLERO D * x x x * TABLERO E +
+ + + + + + * * * x x x * * * + + + + + +
+ + + + + + * * * x x x * * * + + + + + +
+ + + + + + * * * x x x * * * + + + + + +
Cuadro III
MATRIZ DE 21 ∗ 21 UTILIZADA
+ Al cual le llamamos zona 1
* Al cual le llamamos zona 2
o Al cual le llamamos zona 3
x Al cual le llamamos zona 4
V-A. Recorrido de filas y columnas
Como se puede ver en la zona 1, se recorren todas las filas
i, la descripci´on en C de tal regi´on queda en funci´on de las
columnas j de la siguiente manera:
if((j >= 0&&j <= 5)||(j >= 15&&j <= 20))
Para qu´e definimos esta y las dem´as zonas?. . .
Sup´ongase que se quiere insertar un n´umero en la celda
(i = 3, j = 2), est´a cae en la zona 1, para “mirar” la columna
necesitamos saber desde y hasta d´onde debemos recorrer la
matriz de 21 ∗ 21 para insertar tal n´umero y la jugada sea
v´alida de acuerdo a las reglas del juego, por lo tanto si cae
aqu´ı, preguntaremos:
Es la fila i <= 8
Si esto ocurre debemos escanear en la columna j = 2 y las
filas i = 0 a i = 8; en caso contrario preguntaremos:
Es la fila i >= 12
En este caso escanearemos en la columna j = 2 y las filas
i = 12 a i = 20.
Para la zona 2, tenemos la siguiente condici´on:
if((j >= 6&&j <= 8)||(j >= 12&&j <= 14))
Esta zona es muy importante, pu´es aqu´ı es donde los
sudokus simples comparten cada v´ertice con los dem´as, por lo
tanto al querer insertar un valor en esta zona y espec´ıficamente
en uno de estos cuatro bloques, los recorridos deben abarcar
ambos tableros implicados, es decir el tablero del centro con
uno de los dem´as de los extremos.
Primero analizaremos el desde, es decir desde d´onde se
debe empezar a escanear la columna si se quisiese insertar
una valor en ´esta zona. Por lo tanto una vez que estemos en
esta zona nos preguntaremos:
Es i <= 8. Si ocurriese esto el desde es la fila i = 0
Es i >= 12. Si ocurriese esto el desde es la fila i = 12
Por ´utlimo, si no cumple ambos el desde es la fila i = 6.
3. LP1 - UC 3
Luego el hasta, aqu´ı hay que poner mayor atenci´on, y un
grado de concentraci´on, para mayor comprensi´on comp´arese
las condiciones con la Tabla III, Por lo tanto una vez que
estemos en esta zona nos preguntaremos:
Es i <= 5. Si ocurriese esto el hasta es la fila i = 8
Es i >= 12. Si ocurriese esto el hasta es la fila i = 20
Por ´utlimo, si no cumple ambos el hasta es la fila i = 14.
Para la zona 4, son las zonas no permitidas o ignoradas de
la matriz, la condici´on es:
if((i >= 9&&i <= 11)&&((j >= 0&&j <= 5)||(j >= 15&&j <= 20)))
Para las horizontales.
if((j >= 9&&j <= 11)&&((i >= 0&&i <= 5)||(i >= 15&&i <= 20)))
Para las verticales.
Por ´ultimo la zona 3, que es el complemento de todas
las anteriores, es decir todas las celdas de la matriz que
no cumplen con ninguna de las condiciones de las zonas
anteriores.
Ahora vamos a algo concreto, una vez definidos las zonas,
los l´ımites de recorrido(fila, columna), se tiene que para cada
celda (i=fila,j=columna), se define dos funciones:
retorna desde(int i, int j), que no hay casi nada que
explicar que es lo que hace, retorna la cota superior desde
donde se tiene que empezar a “mirar”.
retorna hasta(int i, int j), retorna la cota inferior,
hasta donde se tiene que “mirar”.
Por lo tanto aqu´ı se explica la simetr´ıa, si quisieramos
saber el recorrido en columna, llamamos a la funci´on de
la siguiente manera:
desde = retorna desde(i, j);
Cota superior(primera posici´on, fila de la matriz a recorrer)
hasta = retorna hasta(i, j);
Cota inferior(´ultima posici´on, fila de la matriz a recorrer)
Para el recorrido en fila, es lo mismo, solo que se inter-
cambian los par´ametros de fila por columna y viceversa, es
decir:
desde = retorna desde(j, i);
Cota izquierda(primera posici´on, columna de la matriz a
recorrer)
hasta = retorna hasta(j, i);
Cota derecha(´ultima posici´on, columna de la matriz a recorrer)
V-B. Recorrido del bloque
Es muy sencillo, suponiendo un bloque de 3 ∗ 3 como la
Tabla I, dentro de una matriz de 21∗21, por lo tanto podemos
debemos ver a cada bloque como un multiplo entero de 3,
es decir para cada par (i, j), se puede saber a cu´al de los
bloques pertenece dentro de la matriz, nuestra referencia es
la parte superior izquierda, a partir del cual se desplaza dos
lugares para la derecha y dos lugares para bajo como en la
Tabla IV
Cuadro IV
BLOQUE DE UN SUDOKU, REFERENCIA CELDA NEGRA
Es decir, para cada par (i, j), que se encuentre en cualquier
parte de la matriz de 21 ∗ 21, se puede hallar el (i , j )(celda
negra) al cual pertenece (i, j), de la siguiente manera:
y = (i/3) ∗ 3;
Para la fila, y adem´as
x = (j/3) ∗ 3;
Para la columna, con una notaci´on de par ordenado (x, y)
para mayor entendimiento de la referencia, es importante
resaltar que tanto i como j se declaran con un tipo de dato
int, lo cual da sentido al dividir y multiplicar por 3 lo cual
parecer´ıa algo tonto, pero lo que hace es toma la parte entera
de () y lo multiplica por 3 y eso es asignado a las variables.
VI. DESCRIPCI ´ON DE LA FUNCI ´ON PRINCIPAL
VI-A. Funci´on Solucionador
Esta funci´on es el cerebro, utiliza recursividad, bactracking
con un esquema para todas las soluciones; como dijimos
conceptualmente dividimos la matriz de 21 ∗ 21 en cinco
tableros de sudokus simples; el del centro llamado como B en
la Tabla III es la primordial a nuestro criterio, lo que hacemos
es agotamos todas las soluciones posibles de tal sub-tablero, y
para cada soluci´on verificamos si los tableros A,C,D,E tienen
soluci´on, si esto ocurre se ha encontrado una soluci´on, para
que tal funci´on pueda “distinguir” entre cada sub-tablero, le
etiquetamos un n´umero, tal que:
Tablero A = 1; sector(i = 0, j = 0) a (i = 8, j = 8)
Tablero B = 0; sector(i = 6, j = 6) a (i = 14, j = 14)
Tablero C = 2; sector(i = 0, j = 12) a (i = 8, j = 20)
Tablero D = 3; sector(i = 12, j = 0) a (i = 20, j = 8)
Tablero E = 4; sector(i = 12, j = 12) a (i = 20, j =
20)
En todo el c´odigo se han declarado nueve funciones, si
bien este es un documento de apoyo para entender la l´ogica
seguida y la soluci´on propuesta ya ha cumplido con lo suyo,
por lo tanto las dem´as se describen dentro del c´odigo mismo lo
que realizan y c´omo funcionan, algunas son: lectura de datos,
escritura de solucion, impresi´on e interfaz para consola, entre
otras.
Ultima revisi´on 25 de abril de 2011.
REFERENCIAS
http://www.publispain.com/sudoku/que es sudoku.html
4. This is the first line in the header Page: 1 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define DIMENSION 21
/* definimos la variable de tipo booleano */
typedef int boolean;
#define FALSE 0
#define TRUE 1
//***************************PROTOTIPO DE FUNCIONES********************************
boolean Solucionador( int tablerote[ ][ DIMENSION ], int selector);
int Verificador_Insertar( int tablerote[ ][ DIMENSION ], int i, int j, int valor);
int retorna_desde(int i, int j);
int retorna_hasta(int i, int j);
void carga_tablerote(int tablero_X[][DIMENSION], int contenedor[]);
void lectura_datos(int contenedor[]);
void escritura_datos(int tablerote[][DIMENSION]);
void parametros_recorrido(int vector[], int selector);
//*********************************************************************************
//Ver Sudoku2TXT Pro.pdf adjunto para una mejor comprensión del código
int main()
{
int contenedor[373];
int tablerote[21][21];
lectura_datos(contenedor);
carga_tablerote(tablerote, contenedor);
Solucionador(tablerote,0);//se le pasa el valor "0" que indica el tablero B del centro
return 0;
}
//Ver Sudoku2TXT Pro.pdf adjunto para una mejor comprensión del código
/*+++++++++++++++++++++++++++++++CEREBRO DEL ALGORITMO+++++++++++++++++++++++++++++++++++*/
/* la función solucionador es el "cerebro" de todo el algoritmo, aquí se utilizan técnicas
de programación como recursividad y el famoso bactracking o vuelta atrás, básicamente la
matriz de 21*21 está dividida en 5 tableros individuales o sudokus simples, cada vez que
se quiera insertar una valor de prueba se verifica si se puede hacer(Verificador_insertar)
Printed by Code Visual to Flowchart 1/9
5. This is the first line in the header Page: 2 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
mientras se pueda se avanza, si se llegase a un punto dónde ya no se puede avanzar y todavía
no está resuelto se retrocede y se prueba de otra forma(backtracking).
Vale pa pena mencionar que "selector" es quien dice de qué tablero estamos "hablando", si
es cero(0), es el del medio, en el cual las condiciones son diferentes por compartir sus
vértices con los demás tableros.
Lo que se hace es, se agotan todas las soluciones posibles que pueda tener el tablero
central pues por cada solución que tenga ésta podría o no tener las cuatro restantes al
mismo tiempo; la condicion es if(decision && k == 9 && selector == 0).
En pocas palabras, por cada solución que tenga el tablero del centro(selector == 0) se "ve"
si las demás tienen solución, si esto ocurre el sudoku samurai tiene solución, es por ello
que se busquen todas las soluciones del tablero central que de acuero a nuestras pruebas llega
a valores mayores a las milésimas de acuerdo a la complejidad del sudoku samurai*/
boolean Solucionador( int tablero_X[ ][ DIMENSION ], int selector)
{
int i, j, k, decision;
int vector[4];
/* inicio de filas vector[0]
fin de filas vector[1]
inicio de columnas vector[2]
fin de columnas vector[3]
*/
parametros_recorrido(vector, selector);
for(i = vector[0]; i <= vector[1]; i++){
for(j = vector[2]; j <= vector[3]; j++){
if(tablero_X[ i ][ j ] != 0)//para los números que ya estaban o los que se han
continue; //cargado buscando una solución hasta el momento
for(k = 1; k <= 9; k++){//prueba con cada valor posible(backtraking)
if(Verificador_Insertar( tablero_X, i, j, k )){//verifica fila,columna y bloque
tablero_X[ i ][ j ] = k;//Prueba con un valor y avanza en forma recursiva
decision = Solucionador(tablero_X, selector);//recibe un TRUE o FALSE
if(decision && k == 9 && selector == 0)//para el tablero central y "k==9"
return TRUE; // es para agotar posibilidades
else if(decision && selector != 0)//para los demás tableros de los extremos
return TRUE;
tablero_X[ i ][ j ] = 0;//valor no acertado vuelve a cero y prueba de nuevo
Printed by Code Visual to Flowchart 2/9
6. This is the first line in the header Page: 3 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
}
}
return FALSE;//Si ya no se ha podido avanzar, se vuelve atras con "decision"
}
}
//si se ha encontrado una solución del tablero central, se "ve" si las demás tienen solución
if(selector == 0 && (Solucionador(tablero_X, 1)) && (Solucionador(tablero_X, 2)) && (Solucionador(tablero_X, 3))
&& (Solucionador(tablero_X, 4)) )
escritura_datos(tablero_X);//ha encontrado la solución
return TRUE;
}
/*++++++++++++++++Verifica FILA, COLUMNA, BLOQUE+++++++++++++++++++++++++++++++++++++++++++*/
/*para cada (i,j), devuelve un TRUE o FALSE, para verificar si se puede insertar en tal posicion
el valor "k"*/
int Verificador_Insertar( int tablero_X[ ][ DIMENSION ], int i, int j, int valor)
{
int a, b, x, y;
//Mira columna
a = retorna_desde(i,j);//cota superior (i,j)
b = retorna_hasta(i,j);//cota inferior (i,j)
for( a; a <= b; a++)
{
if(a != i && tablero_X[ a ][ j ] == valor)
{
return FALSE;
}
}
//Mira fila
a = retorna_desde(j,i);//cota izquierda (j,i) -- utiliza la simetría del sudoku,"simplificar"
b = retorna_hasta(j,i);//cota derecha (j,i) -- menor uso de variables y misma función
for(a; a <= b; a++)
{
if(a != j && tablero_X[ i ][ a ] == valor)
{
return FALSE;
}
}
//Mira cuadrado
Printed by Code Visual to Flowchart 3/9
7. This is the first line in the header Page: 4 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
y = ( i / 3 ) * 3;
x = ( j / 3 ) * 3;
for(a = 0; a < 3; a++)
{
for(b = 0; b < 3; b++)
{
if(a != i && b != j && tablero_X[ y + a ][ x + b ] == valor)
{
return FALSE;
}
}
}
return TRUE;
}
/*+++++++++++++++FUNCIÓN QUE RETORNA EL LÍMITE SUPERIOR A RECORRER+++++++++++++++++++++++++++++++++*/
/*retorna_desde y retorna_hasta fueron creadas para simplificar, utilizar simetría
y que el código sea más compacto y fácil de depurar, lo que realiza retorna_desde
es dado una coordenada (i,j), devuelve desde qué "fila" se debe empezar a
recorrer y retorna_hasta devuelve hasta donde se debe recorrer la "fila", esto es
para mirar la columna en cuestión("j").
Para mirar la fila en cuestion("i") es lo mismo, cambiando (j,i) y todo lo explicado por "columna"
aquí es donde se aplica la simetría.
En la matriz de 21*21 se han definido tres zonas en las cuales las condiciones son las mismas
para cada par ordenado(i,j), y una cuarta que son las ignoradas o que no son parte del sudoku
para mejor entendimiento ver sudoku2TXT Pro.pdf adjunto*/
int retorna_desde(int i, int j)
{
if( (j >= 0 && j <= 5) || (j >=15 && j <= 20) )//primera zona
{
if(i <= 8)
return 0;
else
return 12;
}
else if( (j >= 6 && j <= 8) || (j >= 12 && j <= 14) )//segunda zona
{
if(i <= 8)
return 0;
else if(i >= 15)
Printed by Code Visual to Flowchart 4/9
8. This is the first line in the header Page: 5 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
return 12;
else
return 6;
}
else //tercera zona
return 6;
}
/*+++++++++++++++++++++FUNCIÓN QUE RETORNA EL LÍMITE INFERIOR A RECORRER++++++++++++++++++++++++++*/
int retorna_hasta(int i, int j)
{
if( (j >=0 && j <= 5) || (j >= 15 && j <= 20) )//primera zona
{
if(i <= 8)
return 8;
else
return 20;
}
else if( (j >= 6 && j <= 8) || (j >= 12 && j <= 14) )//segunda zona
{
if(i <= 5)
return 8;
else if(i >= 12)
return 20;
else
return 14;
}
else//tercera zona
return 14;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*++++++++++++++++++++++++++++++++++ Carga matriz de 21*21+++++++++++++++++++++++++++++++++++++*/
/*recibe el vector donde se cargaron los datos del txt, y traspasa los valores a la matriz
de 21*21 que se utilizará para representar el sudoku samurai*/
void carga_tablerote(int tablero_X[][DIMENSION], int contenedor[]){
int i, j, k=0;
for(i = 0; i < DIMENSION; i++){
for(j = 0; j < DIMENSION; j++){
//las celdas que no son parte del sudoku o ignoradas
Printed by Code Visual to Flowchart 5/9
9. This is the first line in the header Page: 6 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
if((i>=9 && i <=11)&&((j>=0 && j <=5)||(j>=15 && j<=20)) || ((j>=9 && j <=11)&&((i>=0 && i
<=5)||(i>=15 && i<=20))))
tablero_X[i][j] = 5;//carga un valor cualquiera
else
{
tablero_X[i][j] = contenedor[k];
k++;
}
}
}
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*+++++++++++++++++++++++++++Carga del txt a un vector+++++++++++++++++++++++++++++++++++++++++++*/
/*lee los datos del txt en forma lineal, y va cergando en forna secuencial en un
vector, que luego se cargará en la matriz de 21*21*/
void lectura_datos(int contenedor[]){
int c,z = 0;
char direccion[80];
printf("***********************************************************************n");
printf("ttt UNIVERSIDAD CATOLICAn");
printf("tttPROGRAMA Sudoku2TXT Pron");
printf("tt RAMIREZ, PEDROt COLMAN, ALBERTOn");
printf("***********************************************************************nn");
printf("Introduzca nombre del archivo a solucionar; Ejemplo: nombre.txtnn");
printf("Sudoku2TXT Pro ->");
gets(direccion);
FILE *datos_entrada;
datos_entrada = fopen(direccion, "r");//sera de lectura
if (datos_entrada == NULL)
{
printf("El archivo no existe n");
exit (EXIT_FAILURE);
}
else
{
printf("nn Espere por favor... En busca de alguna soluciOn... Puede tardar varios minutos... nn");
do
Printed by Code Visual to Flowchart 6/9
10. This is the first line in the header Page: 7 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
{
c = getc(datos_entrada); /* Obtiene un caracter del archivo */
//putchar(c);
if(isdigit(c)){//Devuelve un valor verdadero si "c" es un dígito; de lo contrario 0(falso)
contenedor[z] = c - 48;//como lee en ascii se le resta los 48
z +=1;
}
if(c == '-'){//si cumple con esto carga cero a la posicion del vector
contenedor[z] = 0;//que significa celda vacía.
z +=1;
}
}
while (c != EOF); /* hasta encontrar EOF (el final del archivo)*/
}
fclose(datos_entrada);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*++++++++++++++++++++++++++++++++Carga de la matriz al txt--SALIDA--++++++++++++++++++++++++++++*/
/*carga de la matiz de 21*21 a un archivo de texto, toda vez que se halla encontrado
una solución*/
void escritura_datos(int tablero_X[][DIMENSION])
{ int i,j;
char solucion[80];
printf("ntt¡¡¡Solucion encontrada!!!nn");
printf("Introduzca el nombre del archivo resuelto; Ejemplo: nombre.txtn");
printf("nSudoku2TXT Pro->");
gets(solucion);
FILE *datos_salida;
datos_salida = fopen(solucion,"w");//sera de escritura
for(i = 0; i < DIMENSION; i++){
for(j = 0; j < DIMENSION; j++){
if( (j % 21 == 0) && i != 0)
fprintf(datos_salida,"n");
//las celdas que no son parte del sudoku o ignoradas
if((i>=9 && i <=11)&&((j>=0 && j <=5)||(j>=15 && j<=20)) || ((j>=9 && j <=11)&&((i>=0 && i
<=5)||(i>=15 && i<=20))))
fprintf(datos_salida," ");
Printed by Code Visual to Flowchart 7/9
11. This is the first line in the header Page: 8 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
else
fprintf(datos_salida,"%d ", tablero_X[i][j]);
}
}
fprintf(datos_salida, "nnnn¡¡¡Gracias por utilizar Sudoku2TXT Pro!!!n");
fprintf(datos_salida, "n Colmán, Albertot59333-II");
fprintf(datos_salida, "n Ramírez, Pedrot59320-IE");
fprintf(datos_salida, "nn Lenguaje de Programación I");
fprintf(datos_salida, "nt UC - 2011");
fclose(datos_salida);
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*+++++++++++++++++++++++++RETORNA LOS LÍMITES DE CADA SUB-TABLERO+++++++++++++++++++++++++++++++++++++++*/
/*en la matriz de 21*21 están los 5 tableros "individuales" de sudoku simple, con
esta función se retornan en un vector tales sectores, de acuerdo a un valor que
selecciona cuál de tales tableros se quiere sus coordenadas que la limitan, éste
es el "selector".*/
void parametros_recorrido(int vector[], int selector)
{
if(selector == 0)//B
{
vector[0] = 6;//inicio de filas vector[0]
vector[1] = 14;//fin de filas vector[1]
vector[2] = 6;//inicio de columnas vector[2]
vector[3] =14;//fin de columnas vector[3]
}
if(selector == 1)//A
{
vector[0] = 0;
vector[1] = 8;
vector[2] = 0;
vector[3] =8;
}
if(selector == 2)//C
{
vector[0] = 0;
vector[1] = 8;
vector[2] = 12;
Printed by Code Visual to Flowchart 8/9
12. This is the first line in the header Page: 9 of 9
New3 * Print Date: 26/04/2011. Time: 0:05:02
vector[3] =20;
}
if(selector == 3)//D
{
vector[0] = 12;
vector[1] = 20;
vector[2] = 0;
vector[3] =8;
}
if(selector == 4)//E
{
vector[0] = 12;
vector[1] = 20;
vector[2] = 12;
vector[3] = 20;
}
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
Printed by Code Visual to Flowchart 9/9