Foros aprenderaprogramar.com

Aprender a programar => C, C++, C#, Java, Visual Basic, HTML, PHP, CSS, Javascript, Ajax, Joomla, MySql y más => Mensaje iniciado por: DotarSojat en 15 de Octubre 2015, 22:19

Título: Crear sudoku por partes validar el tablero numérico C++ cplusplus
Publicado por: DotarSojat en 15 de Octubre 2015, 22:19
Buenas, tenia que hacer un sudoku por partes, en la primera era validar el tablero numérico, recibiendo un número entero de 16 digitos, Cada valor representará una posición dentro del tablero numérico 4x4, dividido por cuadrantes en la que no pueda haber número repetidos, en filas, columnas o cuadrantes http://prntscr.com/8pzd7b así estaban divididos los cuadrantes, en el tablero, una cadena válida de 16 dígitos, era una que estuviera comprendida con números entero entre  1 y 4, solo se podía hacer utilizando estructura condicionales ( If, if else, switch) esa parte la logre hacer

Código:

Código: [Seleccionar]
#include <iostream>
using namespace std;

int main () {


 int a,b,c,d,e,f,a11,a12,a13,a14,b11,b12,b13,b14,c11,c12,c13,c14,d11,d12,d13,d14;
 unsigned long long int x;
 bool t=true;

 cout<<"introduzca la cadena"<<endl;
 cin>>x;
 


    a=x/100000000;
 b=x%100000000;
 c=a/10000;
 d=a%10000;
 e=b/10000;
 f=b%10000;
 a11=c/1000;
 c=c%1000;
 a12=c/100;
 c=c%100;
 a13=c/10;
 a14=c%10;
 b11=d/1000;
 d=d%1000;
 b12=d/100;
 d=d%100;
 b13=d/10;
 b14=d%10;
 c11=e/1000;
 e=e%1000;
 c12=e/100;
 e=e%100;
 c13=e/10;
 c14=e%10;
 d11=f/1000;
 f=f%1000;
 d12=f/100;
 f=f%100;
 d13=f/10;
 d14=f%10;
 
  //condicional que evalua que el contenga 16 digitos
  if ((x>99999999999999999 && x<10000000000000000)){
   cout<<"Entrada incorrecta la cadena  debe contener 16 digitos"<<endl;
   t=false;
  }
  else { if (((a11!=1) and (a11!=2)  and (a11!=3)  and (a11!=4))  or // condicional que evalua que la cadena introducida contenga numeros entre 1 y 4
   ((a12!=1) and (a12!=2)  and (a12!=3)  and (a12!=4))  or
   ((a13!=1) and  (a13!=2) and (a13!=3)  and (a13!=4))  or 
   ((a14!=1) and  (a14!=2) and  (a14!=3) and (a14!=4))  or
   ((b11!=1) and  (b11!=2) and  (b11!=3) and (b11!=4))  or 
   ((b12!=1) and  (b12!=2) and  (b12!=3) and (b12!=4))  or 
   ((b13!=1) and ( b13!=2) and  (b13!=3) and (b13!=4))  or 
   ((b14!=1) and  (b14!=2) and  (b14!=3) and (b14!=4))  or 
   ((c11!=1) and  (c11!=2) and  (c11!=3) and (c11!=4))  or 
   ((c12!=1) and  (c12!=2) and  (c12!=3) and (c12!=4))  or 
   ((c13!=1) and  (c13!=2) and  (c13!=3) and (c13!=4))  or 
   ((c14!=1) and  (c14!=2) and (c14!=3)  and (c14!=4))  or
   ((d11!=1) and  (d11!=2) and  (d11!=3) and (d11!=4))  or
   ((d12!=1) and (d12!=2)  and (d12!=3)  and (d12!=4))  or 
   ((d13!=1) and  (d13!=2) and (d13!=3)  and (d13!=4))  or 
   ((d14!=1) and  (d14!=2) and  (d14!=3) and (d14!=4))){
          cout<<"Entrada incorrecta, la cadena solo debe poseer digitos entre 1 y 4 "<<endl;
    t=false;}
 else {
     

     
   //condicionales que evaluan cuadrante, filas y columnas que no haya numeros repetidos               


  if ((a11==a12))  {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C1"<<endl;
  cout<<"Digitos repetidos "<<endl;
  cout<<"C1 :"<<
  cout<<"Columna 1:"<< a11<<","<<a12<<endl;
  t=false;}
 
  if ((a11==b11)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C1"<<endl;
  cout<<"Fila 1"<<endl;
  cout<<"digitos repetidos:"<<endl;
  cout<<"C1:"<<a11<<endl;
  cout<<"Fila 1:"<<a11<<","<<b11<<endl;
  t=false;}
 
  if ((a11==b12)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C1"<<endl;
  cout<<"Digitos repetidos "<<endl;
  cout<<"C1:"<<a11<<endl;
   t=false;}
 
  if ((a12==b11)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C1"<<endl;
  cout<<"Digitos repetidos "<<endl;
  cout<<"C1:"<<a12<<endl;
  t=false;}
 
  if ((a12==b12)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C1"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C1:"<<a12<<endl;
  t=false;}
     
  if((b11==b12)) {
  cout<<"Repeticion de digitos en :"<<endl;
  cout<<"C1"<<endl;
  cout<<"Columna 2"<<endl;
  cout<<"Digitos repetidos en"<<endl;
  cout<<"Columna 2:"<<b11<<","<<b12<<endl;
  t=false;}
 
  if ((a13==a14)) {
  cout<<"Repeticion de digitos en"<<endl;
  cout<<"C2"<<endl;
  cout<<"Fila 1"<<endl;
  cout<<"Digitos repetidos en "<<endl;
  cout<<"Fila 1 :"<<a13<<","<<a14<<endl;
  t=false;}
 
  if ((a13==b13)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C2"<<endl;
  cout<<"Columna 1"<<endl;
  cout<<"Digitos repetidos en"<<endl;
  cout<<"Columna 1:"<<a13<<","<<b13<<endl;
  t=false;}
 
  if((a13==b14)) {
  cout<<"Repeticion de digito en:"<<endl;
  cout<<"C2"<<endl;
  cout<<"Digitos repetidos "<<endl;
  cout<<"C2:"<<a13<<endl;
  t=false;}
 
   
  if ((a14==b13)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C2"<<endl;
  cout<<"Digitos repetidos en"<<endl;
  cout<<"C2:"<<a14<<endl;
  t=false;} 
 
  if ((a14==b14)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C2"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C2:"<<endl;
  t=false;} 
 
  if ((b13==b14)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C2"<<endl;
  cout<<"Columna 2"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C2:"<<b13<<endl;
  cout<<"Columna 2:"<<b13<<","<<b14<<endl;
  t=false;}
 
     
  if ((c11==c12)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C3"<<endl;
  cout<<"Fila 3"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C3:"<<c11<<endl;
  cout<<"Fila 3"<<c11<<","<<c12<<endl;
  t=false;}
 
  if ((c11==d11)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C3"<<endl;
  cout<<"Columna 1"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C3:"<<c11<<endl;
  cout<<"Columna 1:"<<c11<<","<<d11<<endl;
  t=false;}
 
  if((c11==d12)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C3"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C3:"<<c11<<endl;
  t=false;} 
 
  if ((c12==d11)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C3"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C13:"<<c12<<endl;
  t=false;}
     
  if ((c12==d12)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C3"<<endl;
  cout<<"Fila 2"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C3:"<<c12<<endl;
  cout<<"Fila 2:"<<c12<<","<<d12<<endl;
  t=false;}   
 
  if((d11==d12)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C3"<<endl;
  cout<<"Columna 4"<<endl;
  cout<<"Digitos repetidos "<<endl;
  cout<<"C3:"<<d11<<endl;
  cout<<"Columna 4:"<<d11<<","<<d12<<endl;
  t=false;}   
 
  if ((c13==c14)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C4"<<endl;
  cout<<"Columna 3"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C4:"<<c13<<endl;
  cout<<"Columna 3:"<<c13<<","<<c14<<endl;
  t=false;}
 
  if ((c13==d13)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C4"<<endl;
  cout<<"Fila 3"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C4:"<<c13<<endl;
  cout<<"Fila 3:"<<c13<<","<<d13<<endl;
  t=false;} 
 
  if ((c13==d14)) {
  cout<<"Repeticion de digitos en :"<<endl;
  cout<<"C4"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C4:"<<c13<<endl;
  t=false;} 
 
  if((c14==d13)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C4"<<endl;
  cout<<"Digitos repetidos"<<endl;
  cout<<"C4:"<<c14<<endl;
  t=false;}   
 
  if ((c14==d14)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C4"<<endl;
  cout<<"Fila 4"<<endl;
  cout<<"Digitos repetidos "<<endl;
  cout<<"Fila 4:"<<c14<<","<<d14<<endl;
  t=false;}   
 
  if ((d13==d14)) {
  cout<<"Repeticion de digitos en:"<<endl;
  cout<<"C4"<<endl;
  cout<<"Columna 4"<<endl;
  cout<<"Digitos repetidos "<<endl;
  cout<<"C4:"<<d13<<endl;
  cout<<"Columna 4:"<<d13<<","<<d14<<endl;
  t=false;}     
 





}       

 if ((t==true)) {
 cout<<"solucion valida"<<endl;}
 else
 {cout<<"Solucion invalida"<<endl;
 }

}     
}   


Pero ahora en la segunda, me piden hacer http://prntscr.com/8pznkk,  http://prntscr.com/8pznxq,  http://prntscr.com/8pzoa8,  http://prntscr.com/8pzokypudiendo utilizar, acciones, funciones, ciclos, arreglos, matrices, registro, hice este código ( Aclaro que esta mal, ya que no hace lo que me piden que haga)

Código:

Código: [Seleccionar]
#include <iostream>
using namespace std;

int mat[9][9];


bool ValidarTablero() {//función que valida que el tablero tenga una solucion valida
 
bool ver=true;

int cont=0,c=0;
 
 for(int i=cont+1;i<9;i++) {
  for(int j=0;j<9;j++) {
   
  if (mat[cont][j]==mat[i][j])
   {if (c>1){{cout<<"Solucion invalida"<<endl;}
   
  ver=false;}
  else
  {cout<<"Solucion Valida"<<endl;
  ver=true;}
  }
   }

 cont++;
 
return (ver);
}
}


void MostrarTablero(){//función que muestra el tablero actual
 
 
 
 
 for(int i=0;i<9;i++){
  for(int j=0;j<9;j++){
 
  cout  <<  mat[i][j];
 
  }
 cout<<""<<endl;
 }
 
}




bool ValidarInsercion () {
bool validar=true;
int x,y,n;
 
 cout<<"ingrese la coordenada x"<<endl;
 cin>>x;
 cout<<"ingrese la coordenada y"<<endl;
 cin>>y;
 cout<<"ingrese el valor"<<endl;
 cin>>n;
 for (int i =0; i<9; i++){
 if (mat[x][i]==n || mat[i][y]==n) {
  validar=true;
  break;

if (validar==true){
  cout<<"valor repetido"<<endl;
}
 
return (validar);
}
}



//accion principal

int main () {
 
int op,op1;
 
 //llena la matriz con puros 0
 for (int i=0; i<9; i++){
 for (int j=0; j<9; j++){
 mat[i][j]=0;
 mat[0][3]=1;
 mat[1][2]=5;
 mat[2][7]=2;
 mat[3][1]=7;
 mat[4][4]=3;
 mat[5][1]=5;
 mat[6][5]=4;
 mat[7][6]=3;
 mat[8][8]=1;
 }
}
 
 
 

 
 
 
 //menu de opciones para la diferente modalidades del juego
 
 cout<<"******MENU******"<<endl;
 cout<<"Eliga la opcion que desea utilizar"<<endl;
 cout<<"1: Cargar Tablero"<<endl;
 cout<<"2: Jugar"<<endl;
 cout<<"3: Salir"<<endl;
 cin>>op;
 
 
 switch(op) {
 
  case 1:
  break;
 
  case 2:
  cout<<"1: Jugada"<<endl;
  cout<<"2: Mostrar Tablero"<<endl;
  cout<<"3: Validar"<<endl;
  cout<<"4: Regresar"<<endl;
  break;
  cout<<"Jugar"<<endl;
  cout<<"Mostrar tablero"<<endl;
  cout<<"Validar"<<endl;
  cout<<"Regresar"<<endl;
  cin>>op1;
  switch (op1){
   case 1:ValidarInsercion();
   break;
   
   case 2:
   MostrarTablero();
   break;
   
   case 3:
   ValidarTablero();
   break;
   
  }
   
   
   
   
   
   }
 
 

 
 
 return 0;
 }


Quisiera saber si pudieran examinar esas acciones y funciones que hice y pudieran aclararme en que falle, y la duda es referente me dijeron que hay una formula de saber si un número esta repetido en un cuadrante o fila con una formula matemática ¿Es cierto? como puedo aplicar eso en mi código, espero me puedan ayudar,
Título: Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
Publicado por: Ogramar en 18 de Octubre 2015, 18:17
Hola DotarSojat es importante que cuando pegues el código lo hagas utilizando las etiquetas [ code] ... [ /code] como se explica en https://www.aprenderaprogramar.com/foros/index.php?topic=1460.0 si no lo haces así el código no se visuliza bien, aparecen cursivas indebidamente, etc.

Hay una cosa con vistas al desarrollo del programa que me parece deberías cambiar en la primera parte: al definir el tablero como 16 valores independientes denominados a11,a12,a13,a14,b11,b12,b13,b14,c11,c12,c13,c14,d11,d12,d13,d14
estás impidiendo (o dificultando) el tratamiento automatizado y recorrido de filas y columnas con bucles.

Para facilitar el tratamiento automatizado y matemático sería más adecuado usar un array o arreglo multidimensional, de modo que trabajes con un array a[][] de dos dimensiones. Si declaras a[4][4] los índices van a ir de 0 a 3. Para evitar tener que partir del índice cero si lo deseas puedes usar a[5][5] y despreciar el elemento de índice cero. Pero en este caso debes tener en cuenta que el número de elementos de cada índice del array no será el valor de length (5) sino length-1, es decir, 4.

Trabajando con arrays deberías evitar el uso de sentencias repetitivas como

if (((a11!=1) and (a11!=2)  and (a11!=3)  and (a11!=4))  or // condicional que evalua que la cadena introducida contenga numeros entre 1 y 4
   ((a12!=1) and (a12!=2)  and (a12!=3)  and (a12!=4))  or

El tratamiento sería basado en bucles e índices de los localizadores, evitando la repetición de código en la medida de lo posible.

El problema quizás se pueda resolver sin usar arrays, pero va a ser una solución menos correcta, más extensa y con más repetición de código.

Fíjate en la solución a sudoku planteada en este hilo (https://www.aprenderaprogramar.com/foros/index.php?topic=1746), basada en arrays.

Luego hay otra cosa que no entiendo: en el primer código que has puesto defines 16 variables, pero en el segundo código sí has usado arreglos (arrays) ¿Por qué? ¿No se supone que es un mismo problema que vas solucionando por partes?

Salu2
Título: Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
Publicado por: DotarSojat en 18 de Octubre 2015, 18:28
Muchas gracias por la respuesta,Ogramar , si es que en el primer código solo podia utilizar las sentecias condicionales ( if-if..else,swicth) Ya en el segundo si podía utilizar los Arrays, struct y archivos, si lo que pasa es que se le va agregando dificultad porque era por fases
Título: Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
Publicado por: Ogramar en 20 de Octubre 2015, 08:50
Dado que es un problema complejo pienso que lo mejor es abordarlo por partes ya que de otro modo se hace difícil de depurar. Lo primero es representar el tablero con una matriz, cosa que ya has hecho. Lo siguiente sería ser capaces de validar el tablero. Para validar el tablero tienes que realizar tres comprobaciones, la primera comprobación podría ser por filas, la segunda por columnas y la tercera por cuadrícula.

Para la primera comprobación hay que mirar que los elementos en una fila no se repiten, esto podrías hacerlo en una función aparte. Habría que comprobar que el primer elemento no es igual a ninguno de los demás, que el segundo no es igual a ninguno de los demás, que el tercero no es igual a ninguno de los demás, etc. Para ello se puede crear un bucle de este tipo, habría que probarlo, esto es solo una idea:

Código: [Seleccionar]
Para k=0 hasta NumeroColumnas-1 //Elemento que se fija de la fila
Para i=0 hasta NumeroFilas-1 //Recorrer filas
Para j=1 hasta NumeroColumnas-2 //Recorrer elementos fila

Si mat[i][k] == mat [i][j] entonces
solucionInvalida = true;
FinSi
FinPara
FinPara
FinPara

Cuando hubieras implementado y probado esta comprobación, pasarías a la comprobación por columnas, una vez hubieras chequeado la comprobación por columnas, pasarías a la solución por cuadrícula... así hasta estar seguro de que te funcione bien la validación del tablero antes de pasar al siguiente punto.

Salu2
Título: Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
Publicado por: DotarSojat en 20 de Octubre 2015, 17:46
y NumeroColumnas-1 y NumeroFilas-1  son enteros declarados antes? valores fijos?
Título: Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
Publicado por: Ogramar en 21 de Octubre 2015, 08:14
Hola, así es, numeroFilas y numeroColumnas son enteros fijos, que serán una declaración inicial para la construcción del programa. La definición del tablero puede verse como la definición de una matriz de nxm elementos (números). Típicamente un sudoku es de 9 filas por 9 columnas, aunque también pueden crearse sudokus con otros números de filas y de columnas.
(https://upload.wikimedia.org/wikipedia/commons/thumb/1/13/Sudoku-by-L2G-20050714.gif/300px-Sudoku-by-L2G-20050714.gif)
Título: Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
Publicado por: DotarSojat en 22 de Octubre 2015, 06:10
Vale, muchas gracias, voy a hacer el intento así como recomendo