Solucionador de Sudokus

David Toledano Villalobos

/*Este programa pide los números de un sudoku ordenados por filas (Ejemplo: Fila 1: 030608027, donde 0 indica lugar a hallar su valor) y, mediante una serie de pasos lógicos devuelve el sudoku con las soluciones encontradas. Si los pasos lógicos no son suficientes para resolver el sudoku, se tiene la posibilidad de añadir números al sudoku manualmente cuando se te pregunte contestando “si”. Al final, si no se ha conseguido resolver por completo el sudoku el programa también devuelve los números que podrían ir en cada posición.*/

#include <iostream>
using namespace std;

void solucion(int fila,int columna,int numero);

int SUDOKU[9][9];
int sudoku[9][9][9];

int main(){
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
SUDOKU[i][j]=0;
}
}
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
for (int k=0;k<9;k++){
sudoku[i][j][k]=1;
}
}
}

string fila;
for(int i=0;i<9;i++){
cout << “Numeros de la fila “<< i+1 <<” (poner 0 si se desconoce el numero): “;
cin >> fila;
for (int j=0;j<9;j++){
solucion(i,j,int(fila[j])-49);
}
}

int pretotal=0, total=1, FIN=0;

int suma=0;

while(FIN<=3){
while(FIN<=2){
total=0;
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
total+=SUDOKU[i][j];
}
}
if(pretotal==total){
FIN+=1;
}
else{
FIN=0;
}
pretotal=total;
for (int n=0;n<9;n++){
//Bloques
for (int g=0;g<3;g++){
for (int h=0;h<3;h++){
suma=0;
for (int i=0;i<3;i++){
for (int j=0;j<3;j++){
suma+=sudoku[3*g+i][3*h+j][n];
}
}
if(suma==1){
for (int i=0;i<3;i++){
for (int j=0;j<3;j++){
if (sudoku[3*g+i][3*h+j][n]==1){
solucion(3*g+i,3*h+j,n);
}
}
}
}
else if(suma==2){
for (int j=0;j<3;j++){
if (sudoku[3*g][3*h+j][n]+sudoku[3*g+1][3*h+j][n]+sudoku[3*g+2][3*h+j][n]==2){
if(sudoku[3*g][3*h+j][n]==0){
for (int i=0;i<9;i++){
sudoku[i][3*h+j][n]=0;
}
sudoku[3*g+1][3*h+j][n]=1;
sudoku[3*g+2][3*h+j][n]=1;
}
else if(sudoku[3*g+1][3*h+j][n]==0){
for (int i=0;i<9;i++){
sudoku[i][3*h+j][n]=0;
}
sudoku[3*g][3*h+j][n]=1;
sudoku[3*g+2][3*h+j][n]=1;
}
else if(sudoku[3*g+2][3*h+j][n]==0){
for (int i=0;i<9;i++){
sudoku[i][3*h+j][n]=0;
}
sudoku[3*g][3*h+j][n]=1;
sudoku[3*g+1][3*h+j][n]=1;
}
}
}
for (int i=0;i<3;i++){
if (sudoku[3*g+i][3*h][n]+sudoku[3*g+i][3*h+1][n]+sudoku[3*g+i][3*h+2][n]==3){
if(sudoku[3*g+i][3*h][n]==0){
for (int j=0;j<9;j++){
sudoku[3*g+i][j][n]=0;
}
sudoku[3*g+i][3*h+1][n]=1;
sudoku[3*g+i][3*h+2][n]=1;
}
else if(sudoku[3*g+i][3*h+1][n]==0){
for (int j=0;j<9;j++){
sudoku[3*g+i][j][n]=0;
}
sudoku[3*g+i][3*h][n]=1;
sudoku[3*g+i][3*h+2][n]=1;
}
else if(sudoku[3*g+i][3*h+2][n]==0){
for (int j=0;j<9;j++){
sudoku[3*g+i][j][n]=0;
}
sudoku[3*g+i][3*h][n]=1;
sudoku[3*g+i][3*h+1][n]=1;
}
}
}
}
else if(suma==3){
for (int j=0;j<3;j++){
if (sudoku[3*g][3*h+j][n]+sudoku[3*g+1][3*h+j][n]+sudoku[3*g+2][3*h+j][n]==3){
for (int i=0;i<9;i++){
sudoku[i][3*h+j][n]=0;
}
sudoku[3*g][3*h+j][n]=1;
sudoku[3*g+1][3*h+j][n]=1;
sudoku[3*g+2][3*h+j][n]=1;
}
}
for (int i=0;i<3;i++){
if (sudoku[3*g+i][3*h][n]+sudoku[3*g+i][3*h+1][n]+sudoku[3*g+i][3*h+2][n]==3){
for (int j=0;j<9;j++){
sudoku[3*g+i][j][n]=0;
}
sudoku[3*g+i][3*h][n]=1;
sudoku[3*g+i][3*h+1][n]=1;
sudoku[3*g+i][3*h+2][n]=1;
}
}
}
}
}
//Filas
for (int i=0;i<9;i++){
suma=0;
for (int j=0;j<9;j++){
suma+=sudoku[i][j][n];
}
if(suma==1){
for (int j=0;j<9;j++){
if (sudoku[i][j][n]==1){
solucion(i,j,n);
}
}
}
if(suma==2){
for (int h=0;h<3;h++){
if (sudoku[i][3*h][n]+sudoku[i][3*h+1][n]+sudoku[i][3*h+2][n]==2){
if (sudoku[i][3*h][n]==0){
for(int j=0;j<3;j++){
for (int g=0;g<3;g++){
sudoku[i/3*3+g][3*h+j][n]=0;
}
}
sudoku[i][3*h+1][n]=1;
sudoku[i][3*h+2][n]=1;
}
else if (sudoku[i][3*h+1][n]==0){
for(int j=0;j<3;j++){
for (int g=0;g<3;g++){
sudoku[i/3*3+g][3*h+j][n]=0;
}
}
sudoku[i][3*h][n]=1;
sudoku[i][3*h+2][n]=1;
}
else if (sudoku[i][3*h+2][n]==0){
for(int j=0;j<3;j++){
for (int g=0;g<3;g++){
sudoku[i/3*3+g][3*h+j][n]=0;
}
}
sudoku[i][3*h][n]=1;
sudoku[i][3*h+1][n]=1;
}
}
}
}
if(suma==3){
for (int h=0;h<3;h++){
if (sudoku[i][3*h][n]+sudoku[i][3*h+1][n]+sudoku[i][3*h+2][n]==3){
for(int j=0;j<3;j++){
for (int g=0;g<3;g++){
sudoku[i/3*3+g][3*h+j][n]=0;
}
}
sudoku[i][3*h][n]=1;
sudoku[i][3*h+1][n]=1;
sudoku[i][3*h+2][n]=1;
}
}
}
}
//Columnas
for (int j=0;j<9;j++){
suma=0;
for (int i=0;i<9;i++){
suma+=sudoku[i][j][n];
}
if(suma==1){
for (int i=0;i<9;i++){
if (sudoku[i][j][n]==1){
solucion(i,j,n);
}
}
}
if(suma==2){
for (int g=0;g<3;g++){
if (sudoku[3*g][j][n]+sudoku[3*g+1][j][n]+sudoku[3*g+2][j][n]==2){
if (sudoku[3*g][j][n]==0){
for(int i=0;i<3;i++){
for (int h=0;h<3;h++){
sudoku[3*g+i][j/3*3+h][n]=0;
}
}
sudoku[3*g+1][j][n]=1;
sudoku[3*g+2][j][n]=1;
}
else if (sudoku[3*g+1][j][n]==0){
for(int i=0;i<3;i++){
for (int h=0;h<3;h++){
sudoku[3*g+i][j/3*3+h][n]=0;
}
}
sudoku[3*g][j][n]=1;
sudoku[3*g+2][j][n]=1;
}
else if (sudoku[3*g+2][j][n]==0){
for(int i=0;i<3;i++){
for (int h=0;h<3;h++){
sudoku[3*g+i][j/3*3+h][n]=0;
}
}
sudoku[3*g][j][n]=1;
sudoku[3*g+1][j][n]=1;
}
}
}
}
if(suma==3){
for (int g=0;g<3;g++){
if (sudoku[3*g][j][n]+sudoku[3*g+1][j][n]+sudoku[3*g+2][j][n]==3){
for(int i=0;i<3;i++){
for (int h=0;h<3;h++){
sudoku[3*g+i][j/3*3+h][n]=0;
}
}
sudoku[3*g][j][n]=1;
sudoku[3*g+1][j][n]=1;
sudoku[3*g+2][j][n]=1;
}
}
}
}
}
//Posiciones
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
suma=0;
for (int n=0;n<9;n++){
suma+=sudoku[i][j][n];
}
if(suma==1){
for (int n=0;n<9;n++){
if (sudoku[i][j][n]==1){
solucion(i,j,n);
}
}
}
}
}
}
if(total<405){
cout << endl;
for (int i=0;i<9;i++){
if (i%3==0){
cout << ” +——-+——-+——-+” << endl;
}
for (int j=0;j<9;j++){
if (j%3==0){
cout << ” | “;
}
else{
cout << ” “;
}
cout << SUDOKU[i][j];
if (j==8){
cout << ” | ” << endl;
}
}
if (i==8){
cout << ” +——-+——-+——-+” << endl;
}
}
string datos;
cout << endl << “Vas a introducir datos nuevos (si/no)? “;
cin >> datos;
while (datos==”si”){
FIN=0;
int fila;
int columna;
int numero;
cout << “Fila: “;
cin >> fila ;
cout << “Columna: “;
cin >> columna;
cout << “Numero: “;
cin >> numero;
solucion(fila-1,columna-1,numero-1);
cout << “Vas a introducir datos nuevos (si/no)? ” ;
cin >> datos;
}
FIN+=1;
}
else{
FIN+=1;
}
}
cout << endl << “El sudoku queda asi:” << endl;
for (int i=0;i<9;i++){
if (i%3==0){
cout << ” +——-+——-+——-+” << endl;
}
for (int j=0;j<9;j++){
if (j%3==0){
cout << ” | “;
}
else{
cout << ” “;
}
cout << SUDOKU[i][j];
if (j==8){
cout << ” | ” << endl;
}
}
if (i==8){
cout << ” +——-+——-+——-+” << endl;
}
}
if (total<405){
cout << endl << “Las posibles soluciones que faltan en el sudoku son:” << endl;
for (int i=0;i<9;i++){
for (int j=0;j<9;j++){
for (int k=0;k<9;k++){
if (sudoku[i][j][k]==0){
cout << “-“;
}
else{
cout << k+1;
}
}
cout << ” “;
}
cout << endl;
}
}

return 0;
}

void solucion(int fila,int columna,int numero){
if(numero>=0){
if(sudoku[fila][columna][numero]==1){
for (int i=0;i<9;i++){
sudoku[i][columna][numero]=0;
}
for (int j=0;j<9;j++){
sudoku[fila][j][numero]=0;
}
for (int k=0;k<9;k++){
sudoku[fila][columna][k]=0;
}
int filabloque=fila/3;
int columnabloque=columna/3;
for (int i=0;i<3;i++){
for (int j=0;j<3;j++){
sudoku[3*filabloque+i][3*columnabloque+j][numero]=0;
}
}
SUDOKU[fila][columna]=numero+1;
}
else{
cout << endl << “Error: Se ha intentado introducir el numero ” << numero+1 << ” en la fila ” << fila+1 << ” y columna ” << columna+1 << ” cuando sus posibles soluciones son “;
for (int k=0;k<9;k++){
if (sudoku[fila][columna][k]==0){
cout << “-“;
}
else {
cout << k+1;
}
}
}
}
}

Acerca de programacion1z

Curso de introducción a la programación en C
Esta entrada fue publicada en Informática e Internet. Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s