Autor Tema: Crear sudoku por partes validar el tablero numérico C++ cplusplus  (Leído 7885 veces)

DotarSojat

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 26
    • Ver Perfil
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/8pznkkhttp://prntscr.com/8pznxqhttp://prntscr.com/8pzoa8http://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,
« Última modificación: 18 de Octubre 2015, 17:44 por Ogramar »

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
« Respuesta #1 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

DotarSojat

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 26
    • Ver Perfil
Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
« Respuesta #2 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

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
« Respuesta #3 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

DotarSojat

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 26
    • Ver Perfil
Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
« Respuesta #4 en: 20 de Octubre 2015, 17:46 »
y NumeroColumnas-1 y NumeroFilas-1  son enteros declarados antes? valores fijos?

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
« Respuesta #5 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.

DotarSojat

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 26
    • Ver Perfil
Re:Crear sudoku por partes validar el tablero numérico C++ cplusplus
« Respuesta #6 en: 22 de Octubre 2015, 06:10 »
Vale, muchas gracias, voy a hacer el intento así como recomendo

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".