Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: ogpg007 en 12 Marzo 2012, 03:42 am



Título: Ayuda con programa que realiza sudokus
Publicado por: ogpg007 en 12 Marzo 2012, 03:42 am
Hola! Soy un principiante en C y os quisiera preguntar para ver si me pudieres ayudar en este programa.   

Lo que hago es definir la función llamada numeros, donde veo las posibilidades de realizar el sudoku ordenando los números de la manera respectiva, es decir, sin que se repitan numeros en cada fila o columna.
Hasta el momento llevo esto:

/*Sudokus*/
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
int x,y,num[9][9], i, h, j, k;

void numeros () {
for (i=0; i<9; i++) {
for (h=0; h<9; h++) {
num[h]=(rand() % 9)+1;
numh: for (j=1; j<h+1; j++) {
if (num[h]==num[h-j]) {
num[h]=(rand() % 9)+1;
goto numh;
}
}
numi: for (k=1; k<i+1; k++) {
if (num[h]==num[i-k][h]) {
num[h]=(rand()%9)+1;
goto numi;
}
}
}
}
}

void main () {
clrscr ();
numeros();
for (j=0; j<9; j++) {
for (k=0; k<9; k++) {
printf ("%d ", num[j][k]);
}
}
getch();
}

Donde está verificando con perfección para que no se repitan números en las columnas, pero en las filas siempre tengo problemas y no sé por qué se dan. Gracias.


Título: Re: Ayuda con programa que realiza sudokus
Publicado por: do-while en 12 Marzo 2012, 14:44 pm
¡Buenas!

Si pretendes solucionar sudokus de esta forma, habra muchos casos en los que no puedas resolverlos. Por poner un ejemplo, si tienes dos numeros que ocupan dos casillas, aunque no sepas en que casilla va cada uno de los numeros, no tendrias en cuenta que en ninguna de esas dos casillas no puede ir ningun otro numero... (esto mismo puedes aplicarlo a tres numeros en tres casillas, cuatro...)

Lo mejor para solucionar cualquier sudoku sin sudar demasiado aplicando un monton de reglas añadidas a las basicas es utilizar backtracking con fuerza bruta. De esta forma incluso sabras si lo que tienes entre manos es un sudoku o si no lo es (por tener mas de una solucion)

¡Saludos!


Título: Re: Ayuda con programa que realiza sudokus
Publicado por: theluigy13etv en 12 Marzo 2012, 15:51 pm
Usa la técnica del Backtracking!!. El código hecho por uno de mi univ. es el siguiente:

Citar

#include<cstdio>
#include<cstring>
using namespace std;
 
bool resuelto;
 
int t[9][9];
 
bool Fil[9][10];
bool Col[9][10];
bool Cua[9][10];
 
void print(){
    for(int i=0;i<9;++i){
        for(int j=0;j<9;++j){
            printf("%d",t[j]);
        }
        puts("");
    }
}
 
void back(int fil,int col){
    if(resuelto==true){
        return;
    }
   
    if(fil==9){
        resuelto=true;
        print();
        return;
    }
    if(t[fil][col]>0){
        back(col<8?fil:fil+1,col<8?col+1:0);
        return;
    }
    int cua=(fil/3)*3+col/3;
    for(int i=1;i<=9;++i){
        if(Fil[fil]==true)continue;
        if(Col[col]==true)continue;
        if(Cua[cua]==true)continue;
        t[fil][col]=i;
        Fil[fil]=true;
        Col[col]=true;
        Cua[cua]=true;
        back(col<8?fil:fil+1,col<8?col+1:0);
        t[fil][col]=0;
        Fil[fil]=false;
        Col[col]=false;
        Cua[cua]=false;
    }
}
 
void caso(){
    resuelto=false;
    memset(Fil,false,sizeof(Fil));
    memset(Col,false,sizeof(Col));
    memset(Cua,false,sizeof(Cua));
    for(int i=0;i<9;++i){
        for(int j=0;j<9;++j){
            scanf("%1d",&t[j]);
            Fil[t[j]]=true;
            Col[j][t[j]]=true;
            Cua[(i/3)*3+j/3][t[j]]=true;
        }
    }
    //print();
    //puts("***************");
    back(0,0);
}
 
int main(){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;++i){
        caso();
    }
}