Estoy haciendo un programa para la facultad y no logro resolverlo, me gustaria saber si podrias ayudarme.
El programa consta en hacer un SUDOKU que es un juego
Los de la universidad me dieron una gia para que yo pueda hacerlo asi y es esta
begin
inicializar-estructuras;
leer-sudoku;
repeat
desplegar numero de recorrida;
para cada celda (i,j) hacer
if (existe d unico en (i,j)) then
begin
asignar d a la celda (i,j);
desplegar "(i,j) -> d (unico)"
end
else if (existe d exclusivo en (i,j)) then
begin
asignar d a la celda (i,j);
desplegar " (i,j) -> d (exclusivo)";
end;
incrementar numero de recorrida;
until (sudoku-completo) o (no-hubo-cambios);
if no-hubo-cambios then
desplegar mensaje;
mostrar sudoku
end
Estructuras de datos
La definición del tablero es clara:
type
Digito = '0'..'9';
TTablero = array [1..9,1..9] of Digito;
Los ceros se utilizan para representar los lugares vacíos. Los dígitos también podrían ser enteros, pero no hay necesidad puesto que no se realiza ninguna aritmética sobre ellos.
Es fundamental poder manejar el conjunto de candidatos de cada celda. Una opción es calcularlo cada vez que se necesita, pero esto es muy costoso. La mejor opción parece ser una estructura así:
type
TCandidatos = array [1..9,1..9] of ConjDeDigitos;
Donde ConjDeDigitos es un tipo que representa el conjunto de candidatos de una celda. Se puede definir de varias maneras. Recomendamos la siguiente representación:
ConjDeDigitos = array [1..10] of Char;
Esta representación es un array con centinela. Se ocupan los primeros lugares del arreglo con los elementos del conjunto y se utiliza un carácter especial para marcar el fin de los datos.
Así, por ejemplo el conjunto {1,2,3} se puede representar así:
1
3
2
@
?
x
a
5
7
#
Observar:
El orden no es relevante.
El centinela es '@'
Los caracteres luego del centinela son “basura”.
El conjunto vacío se representa con un arreglo cuyo primer elemento es el centinela.
Es necesario implementar algunas operaciones mínimas para el tipo conjunto de dígitos:
function esVacioConj(conj : ConjDeDigitos): boolean
procedure quitarConj(d : Digito; var conj: ConjDeDigitos)
function largoConj(conj : ConjDeDigitos) : integer
function pertenece(d : digito; conj: ConjDeDigitos): boolean
Se pueden agregar más operaciones de ser necesarias. Puede ser útil una operación para descubrir candidatos únicos:
function esUnico(d : Digito; conj: ConjDeDigitos): boolean
Algunas líneas generales:
Al inicio comenzamos con el tablero vacío y los conjuntos de candidatos completos.
Se recomienda hacer un procedimiento que permita colocar un dígito en una celda del tablero y actualice todos los conjuntos de candidatos afectados.
La lectura del sudoku llama al procedimiento anterior para cada dítigo del tablero (distinto de cero).
Acerca de las recorridas
El programa contiene muchas recorridas parciales y totales de las estructuras. Muchas de estas recorridas buscan alguna celda con cierta condición (por ejemplo cuando queremos verificar si un candidato es exclusivo). Es imporatante no continuar la recorrida una vez que se encontró lo deseado (dicho de otro modo, no hacerlas con for)
Sobre la región
Una de las recorridas más complejas es la de la región. Una ayuda para recorrer la región que contiene una celda:
function comienzoRegion(i : Rango): Rango;
begin
comienzoRegion:= (i - 1) div 3 * 3 + 1
end;
function finRegion(i : Rango): Rango;
begin
finRegion:= ((i - 1) div 3 + 1) * 3
end;
Estas dos funciones nos permiten hallar rápidamente la columna o fila de comienzo y fin de una región. Si se desea recorrer completamente la región que contiene a la celda (i,j) se puede hacer lo siguiente:
for k:= comienzoRegion(i) to finRegion(i) do
for p:= comienzoRegion(j) to finRegion(j) do
...
Observar que si la recorrida es una búsqueda la estructura FOR no sería la adecuada.
Este es el codigo que llevo yo:
PROGRAM tarea(INPUT,OUTPUT]
TYPE
NUMEROS='0'..'9'
VALORES=ARRAY[1..10] OF NUMEROS
CANDIDATOS=ARRAY[1..9,1..9] OF VALORES
MATRIX=ARRAY[1..9,1..9] OF NUMEROS
VAR
POSIBLES=CANDIDATOS
M=MATRIX
PROCEDURE CARGARNRO(var v:VALORES)
VAR
nro:integer
BEGIN
FOR nro:=1 to 10
BEGIN
if nro=10 then
v[nro]:='@'
else
v[nro]:=chr(48+nro)
END
END
FUNCTION comienzoRegion(i : integer):integer;
BEGIN
comienzoRegion:= (i - 1) div 3 * 3 + 1
END;
FUNCTION finRegion(i : integer):integer;
BEGIN
finRegion:= ((i - 1) div 3 + 1) * 3
END
PROCEDURE XFILA (var hab:VALORES,fila:integer,var m:MATRIX)
VAR
i,j:integer
nro:char
BEGIN
FOR i:=1 to 9 do
BEGIN
nro:=m[fila,i]
FOR j:=1 to 9 do
if hab[j]=nro then
hab[j]:='0'
END
END
PROCEDURE XCOL(var hab:VALORES,col:integer,var m:MATRIX)
VAR
i,j:integer
nro:char
BEGIN
FOR i:=1 to 9 do
BEGIN
nro:=m[fila,i]
FOR j:=1 to 9 do
if hab[j]=nro then
hab[j]:='0'
END
END
PROCEDURE XREG(var hab:VALORES,fil,col:integer,var m:MATRIX)
VAR
i,j,k:integer
nro:char
BEGIN
FOR i:= comienzoRegion(col) to finRegion(col) do
BEGIN
FOR j:= comienzoRegion(fil) to finRegion(fil) do
BEGIN
nro:=m[i,j]
FOR k:=1 to 9 do
BEGIN
if hab[k]:=nro then
hab[k]:='0'
END
END
END
END
PROCEDURE HABILITADOS(var matriz:MATRIX;var aux:POSIBLES)
VAR
i,j:integer
v

osibles
BEGIN
FOR i:=1 to 9 do
BEGIN
FOR j:=1 to 9 do
BEGIN
if matriz[i,j]:='0' then
BEGIN
CARGARNRO(v)
XFILA(v,i,matriz)
XCOL(v,j,matriz)
XREG(v,i,j,matriz)
FOR k:=1 to 10 do
aux[i,j,k]:=v[k]
END
else
BEGIN
for k:=1 to 10 do
aux[i,j,k]:='0'
END
END
END
END
PROCEDURE CARGARMATRIX(var matriz:MATRIX)
VAR
fil,col:integer
nro:char;
BEGIN
FOR fil:=1 to 9 do
BEGIN
WHILE col<=9 do
BEGIN
READ(nro)
IF nro in ['0'..'9'] then
BEGIN
matriz[fil,col]:=nro
col:=col+1
END
END
END
END
--------> *empieza aca el programa despues se llama a la funciones CARGARMATRIX y HABILITADOS*
BEGIN
CARGARMATRIX(M)
HABILITADOS(M,POSIBLES)
REPEAT
for i:1 to 9 do
writeln('posibles para fila 1 y columna ',i,' ---> ', POSIBLES[1,i])
write('escribir el j : ');read(j)
UNTIL j=0
me gustaria poder seguirlo pero no se como seguirlo, si podes ayudarme seria de mucha ayuda.
Desde ya muchas gracias