Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1132 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Sudoku

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Sudoku

n°1872490
Manudesboi​s
Posté le 13-04-2009 à 18:08:23  profilanswer
 

Bonjour!
 
Je suis actuellement en L2 à la fac où je fais un peu de programmation, et mon groupe et moi avons un projet, qui consiste, entre autres, à proposer un programme de résolution de Sudoku de toute taille(nous ne nous sommes encore penchés que sur des grilles carrées), mais voilà que nous avons un problème dans notre début de programme que nous n'expliquons pas (pour l'initialisation de la grille à résoudre).
 
Je vous mets une partie de ce que nous avons fait, la partie qui nous intéresse et où il y a un problème. Si quelqu'un peut prendre le temps de tout lire, comprendre, et nous trouve d'où vient notre bug, ça nous aidera vraiment beaucoup.
 
Nous implémentons notre grille de sudoku comme un tableau 2D avec des pointeurs.
Nous définissons une structure de données "element" qui représente les éléments que l'on aura dans notre tableau 2D.

Code :
  1. struct element {
  2. int ValeurFinale;
  3. int valposs[];
  4. }


 
Dans chaque case, il y a donc un tableau valposs[] qui contient tous les valeurs possibles de la case, et des 0 pour remplacer les valeurs qu'on a deviné improbables.
Exemple, si 1,3,5 est l'ensemble des valeurs possibles dans notre case de sudoku 9*9, le valposs correspondant est:
[1,0,3,0,5,0,0,0,0]
 
La ValeurFinale de chaque case vaut 0 tant qu'on ne sait pas quoi mettre dans cette case
(c'est-à-dire tant que le tableau valposs[] contient plus d'une valeur non-nulle), et quand il n'y a plus qu'une valeur non-nulle dans valposs[] on attribue cette valeur à ValeurFinale.
 
 
 

Code :
  1. #include <iostream>
  2. #include <math.h>
  3. using namespace std;
  4. struct element{
  5.     int ValeurFinale;
  6.     int valposs[] ;
  7.     };
  8. //---------------------------------------------------------------------------------------------------------
  9. //Fonction qui teste si n est un carré parfait:
  10. bool EstUnCarre(int n){
  11.     return (sqrt(n)==floor(sqrt(n)));
  12.     }
  13. //----------------------------------------------------------------------------------------------------------
  14. //Remplissage des valeurs finales avec des 0
  15. void remplissage0(int n,element* grille[])
  16. {
  17.     for (int i=0;i<n;i++)
  18.     {
  19.         for(int j=0;j<n;j++)
  20.         {
  21.             grille[i][j].ValeurFinale=0;
  22.         }
  23.     }
  24. }
  25. //----------------------------------------------------------------------------------------------------------
  26. //Affichage: affiche "X " quand la valeur finale est un 0, "v " quand la valeur finale v s'écrit en deux chiffres, et  //"v  " quand elle s'écrit en un chiffre pour que l'affichage soit propre
  27. void affichage(int n,element* grille[])
  28. {    for (int i=0;i<n;i++)
  29.         {for(int j=0;j<n;j++)
  30.             {if (grille[i][j].ValeurFinale==0)
  31.                {cout<<"X  ";}
  32.              else
  33.                 {   if(grille[i][j].ValeurFinale>9)
  34.                         {cout<<grille[i][j].ValeurFinale<<" ";}
  35.                     else
  36.                         {cout<<grille[i][j].ValeurFinale<<"  ";}
  37.                 }
  38.             }
  39.         cout<<endl;
  40.         }
  41. }
  42. //-----------------------------------------------------------------------------------------------------------
  43. //remplissage des tableaux de valeurs possibles dans chaque case
  44. void remplissageVP(int n,element* grille[])
  45. {
  46.     for(int i=0; i<n; i++)
  47.         {for(int j=0; j<n; j++)
  48.             {for (int k=0; k<n; k++)
  49.                 {grille[i][j].valposs[k]=k+1;
  50.                 }
  51.             }
  52.         }
  53. }
  54. //---------------------------------------------------------------------------------------------------------
  55. //affichage des tableaux de valeurs possibles de chaque case
  56. void affichageVP(int n, element* grille[])
  57. {
  58.     for(int i=0; i<n; i++)
  59.         {for(int j=0; j<n; j++)
  60.             {for (int k=0; k<n; k++)
  61.                 {
  62.                 cout<<grille[i][j].valposs[k];
  63.                 }
  64.             cout<<"  ";
  65.             }
  66.             cout<<endl;
  67.         }
  68. }
  69. //-----------------------------------------------------------------------------------------------------------
  70. void remplissageEtAffichageVP(int n,element* grille[])
  71. {
  72.     for(int i=0; i<n; i++)
  73.         {for(int j=0; j<n; j++)
  74.             {for (int k=0; k<n; k++)
  75.                 {grille[i][j].valposs[k]=k+1;
  76.                 cout<<grille[i][j].valposs[k];
  77.                 }
  78.             cout<<"  ";
  79.             }
  80.             cout<<endl;
  81.         }
  82. }
  83. //-----------------------------------------------------------------------------------------------------------
  84. //...
  85. //-----------------------------------------------------------------------------------------------------------
  86. //-------------------------------------MAIN----------------------------------------------------------//
  87. int main ()
  88. {
  89. //----------------------------------Initialisation de la grille--------------------------------------//
  90.     int n;
  91.     int comptRemplissage=0;
  92.     //comptRemplissage sert uniquement pour la résolution, il compte le nombre de valeurs qui ont été rentrées    //dans la grille de Sudoku.
  93.     //Quand comptRemplissage atteint n²(81 pour une grille basique), c'est qu'on a terminé de la résoudre.
  94.     cout<<"Saisir la taille de la grille (nombre de cases par ligne, par colonne ou par carre)"<<endl;
  95.     do
  96.     {
  97.         cin>>n;
  98.         if (!(EstUnCarre(n)))
  99.         {
  100.             cout<<"Taille invalide, saisissez une taille valide"<<endl;
  101.         }
  102.     }while(!(EstUnCarre(n)));
  103. //allocation dynamique
  104. element **grille = new element* [n];
  105.    for (int i = 0; i < n; i++)
  106.       {grille[i] = new element[n];}
  107. //Remplissage avec des 0
  108.     remplissage0(n,grille);
  109. //Affichage
  110.     affichage(n,grille);
  111. //Remplissage et Affichage des valeurs possibles: 1ère façon:
  112. remplissageVP(n,grille);
  113. affichageVP(n,grille);
  114. //Remplissage et Affichage des valeurs possibles: 2ème façon:
  115. //remplissageEtAffichageVP(n,grille);
  116. ...


 
Il n'y a aucun problème de compilation, mais nous avons quelque chose d'étrange à l'exécution: une différence anormale entre la 1ère et la 2ème façon d'afficher nos valeurs possibles, mais dans les deux cas, la suite du programme donne des résultats complètement faux, et nous pensons que le problème qui suit est engendré par ce problème-là au niveau des valeurs possibles des cases.
 
(dans la suite du programme, nous faisons la saisie des valeurs initiales de la grille, et, par exemple, lorsque nous mettons uniquement un 1 dans la première ligne, première colonne, l'affichage de la grille donne un truc du genre
1  1  X  1
4  1  X  1
3  1  X  1
3  1  X  1            pour une grille 4*4)
 
 
1ère façon:

Citation :

Saisir la taille de la grille (nombre de cases par ligne, par colonne ou par carre)
4
X  X  X  X
X  X  X  X
X  X  X  X
1234 1234 1234 1234
1234 1234 1234 1234
1234 1234 1234 1234
1234 1234 1234 1234


 
2ème façon:

Citation :

Saisir la taille de la grille (nombre de cases par ligne, par colonne ou par carre)
4
X  X  X  X
X  X  X  X
X  X  X  X
1111 1112 1123 1231
1111 1112 1123 1231
1111 1112 1123 1231
1111 1112 1123 1234


 
Voilà tout, si vous êtes disposés à nous aider nous vous en serons reconnaissants. S'il y a quelque chose qui n'est pas clair dans mon explication du programme, demandez-moi s'il vous plaît.
 
Merci
 

mood
Publicité
Posté le 13-04-2009 à 18:08:23  profilanswer
 

n°1872511
Joel F
Real men use unique_ptr
Posté le 13-04-2009 à 19:16:40  profilanswer
 

En C++, les tabelaux c'est vector pas des structures moches.
Ensuite, vous verrait que ca ira mieux :o
 
C'ets quoi cette fac ou on parle pas de la STL en L2 ?

n°1872518
Manudesboi​s
Posté le 13-04-2009 à 19:43:57  profilanswer
 

On ne connaît pas bien les vecteurs (à peine vus en Java), et je ne vois pas en quoi ça nous arrangerait?
 
Je veux bien que notre structure soit moche, mais elle n'est pas incorrecte a priori?
 
Merci quand même pour la réponse.

n°1872533
Joel F
Real men use unique_ptr
Posté le 13-04-2009 à 21:01:50  profilanswer
 

si ...
 
int valpos[]; n'a pas le sens que tu crois ...
En C++, la mémoire on l'allour dynamiquement et c'ets chaint et c'ets exactement ce que gére vector<>.
 
Encore une victime de JAVA v_v

n°1872549
Taz
bisounours-codeur
Posté le 13-04-2009 à 22:17:25  profilanswer
 

Joel F a écrit :

si ...
 
int valpos[]; n'a pas le sens que tu crois ...
En C++, la mémoire on l'allour dynamiquement et c'ets chaint et c'ets exactement ce que gére vector<>.
 
Encore une victime de JAVA v_v


Je dirais pas victime, mais bon quand on change de langage, c'est con de présumer que ca fonctionne pareil.
 
Mais quand même victime, péter du java et faire de la struct avec des fonctions bien moches, ça le fait bien

n°1872550
Manudesboi​s
Posté le 13-04-2009 à 22:23:11  profilanswer
 

ah donc en fait le problème viendrait du valposs[], et c'est lui que tu voudrais remplacer par un Vector?

 

C'est vrai qu'on n'a jamais défini la place que prenait notre tableau valposs[] en mémoire pour chaque case...
Y a-t-il un moyen de faire ça sans passer par un vecteur, histoire que mon groupe et moi restions dans des choses qu'on connaît?

Message cité 1 fois
Message édité par Manudesbois le 13-04-2009 à 22:29:14
n°1872554
Taz
bisounours-codeur
Posté le 13-04-2009 à 22:39:01  profilanswer
 

Bah utiliser la même syntaxe pour valposs que pour tes autres pointeurs, faire les mêmes new et delete

n°1872555
Taz
bisounours-codeur
Posté le 13-04-2009 à 22:42:27  profilanswer
 

Manudesbois a écrit :

ah donc en fait le problème viendrait du valposs[], et c'est lui que tu voudrais remplacer par un Vector?
 
C'est vrai qu'on n'a jamais défini la place que prenait notre tableau valposs[] en mémoire pour chaque case...
Y a-t-il un moyen de faire ça sans passer par un vecteur, histoire que mon groupe et moi restions dans des choses qu'on connaît?


A toi de voir si ça vaut le coup d'apprendre un peu pour supprimer plein de lignes de codes ou pas.

n°1872677
Manudesboi​s
Posté le 14-04-2009 à 11:10:53  profilanswer
 

OK.
 
Si je mets  

Code :
  1. int* valposs;


dans mon struct à la place de  

Code :
  1. int valposs[];


 
et qu'ensuite ligne 143 je mets
 

Code :
  1. for (int i=0;i<n;i++)
  2.     {
  3.         for (int j=0;j<n;j++)
  4.             {
  5.                 int* grille[i][j].valposs = (int*)malloc (n*sizeof(int));
  6.             }
  7.     }


 
c'est pas bon?
 

n°1872692
Joel F
Real men use unique_ptr
Posté le 14-04-2009 à 11:22:21  profilanswer
 

Diantre, v_v.
La manière propre d'allouer un tableau à 2 dimensiosn :
http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0

 

cf fin du fil.


Message édité par Joel F le 14-04-2009 à 11:22:54
mood
Publicité
Posté le 14-04-2009 à 11:22:21  profilanswer
 

n°1872708
Taz
bisounours-codeur
Posté le 14-04-2009 à 11:33:19  profilanswer
 

Manudesbois a écrit :

OK.

 

Si je mets

Code :
  1. int* valposs;


dans mon struct à la place de

Code :
  1. int valposs[];
 

et qu'ensuite ligne 143 je mets

 
Code :
  1. for (int i=0;i<n;i++)
  2.     {
  3.         for (int j=0;j<n;j++)
  4.             {
  5.                 int* grille[i][j].valposs = (int*)malloc (n*sizeof(int));
  6.             }
  7.     }
 

c'est pas bon?

 


 


C'est marrant ça. Je te dis tout pareil avec new, et tois tu sors un malloc ...
Et puis la syntaxe n'est pas bonne.

 

Tout pareil j'ai dit.


Message édité par Taz le 14-04-2009 à 11:33:52
n°1872718
Mxtrem
Posté le 14-04-2009 à 11:45:19  profilanswer
 

Deux manières d'aborder la résolution de sudoku en algo.
Le backtracking :
Tu essaies un chiffre, tu continues tant que ça va, puis si jamais ça chies, tu reviens en arrière tant que la résolution foire.
C'est une méthode simple mais peu efficace en terme de complexité (quoi que tu peux la sophistiquer un peu en faisant des vérifications "a priori" ).
 
Je n'aborderais pas la seconde technique nommée "dancing links", d'une part parcequ'il y a de nombreux tutos à ce sujet sur le net, d'autre part car je n'ai pas réussi à l'implémenter. (En même temps on a eu deux jours pour faire ce projet :D)

n°1872746
Manudesboi​s
Posté le 14-04-2009 à 12:08:02  profilanswer
 

Citation :

Deux manières d'aborder la résolution de sudoku en algo.
Le backtracking :
Tu essaies un chiffre, tu continues tant que ça va, puis si jamais ça chies, tu reviens en arrière tant que la résolution foire.
C'est une méthode simple mais peu efficace en terme de complexité (quoi que tu peux la sophistiquer un peu en faisant des vérifications "a priori" ).
 
Je n'aborderais pas la seconde technique nommée "dancing links", d'une part parcequ'il y a de nombreux tutos à ce sujet sur le net, d'autre part car je n'ai pas réussi à l'implémenter. (En même temps on a eu deux jours pour faire ce projet :D)


 
Merci pour l'info, mais notre problème n'est pas vraiment là, la méthode de résolution, en théorie on l'a^^
C'est juste que le remplissage de la grille foire :/
 

Citation :

C'est marrant ça. Je te dis tout pareil avec new, et tois tu sors un malloc ...
Et puis la syntaxe n'est pas bonne.
 
 
Tout pareil j'ai dit.


 
Oui, j'avais essayé un new quand même avant^^ (sans succès)

n°1872749
Taz
bisounours-codeur
Posté le 14-04-2009 à 12:12:08  profilanswer
 

grille[i][j].valposs = new int[n];
 
copié/collé quoi

n°1872751
Manudesboi​s
Posté le 14-04-2009 à 12:13:43  profilanswer
 

toujours avec

Code :
  1. int* valposs;


dans le struct.
 
et à la ligne 143:

Code :
  1. for (int i=0;i<n;i++)
  2.     {
  3.         for (int j=0;j<n;j++)
  4.             {
  5.                 int* grille[i][j].valposs = new int[n];
  6.             }
  7.     }


 
et voici ce que le compilo dit:
 

Citation :

143 error: expected initializer before '.' token


 

n°1872753
Manudesboi​s
Posté le 14-04-2009 à 12:15:01  profilanswer
 

ah cool, sans le int* devant, ça marche, merci!

n°1872757
Manudesboi​s
Posté le 14-04-2009 à 12:19:30  profilanswer
 

Wouhou! Le bug des 1211 a disparu! Merci beaucoup Taz, tu me sauves!
 
(au passage, si on enlève le int* devant, c'est pourquoi? Parce que grille[i][j].valposs existe déjà?)
 
Et pour éviter un autre problème, à la fin, il faut bien faire:
 

Code :
  1. for (int i=0;i<n;i++)
  2.     {
  3.         for (int j=0;j<n;j++)
  4.             {
  5.                 delete [] grille[i][j].valposs;
  6.             }
  7.     }


 
n'est-ce pas?


Message édité par Manudesbois le 14-04-2009 à 12:23:01

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Sudoku

 

Sujets relatifs
sudoku en C !Quel est le meilleur moyen de réaliser une grille de sudoku avec GTK ?
Algo en rapport avec un sudoku, helpSujet sudoku en python
Solveur de Sudoku[Résolu] Sudoku, trouver les coordonnées d'un tableau 3x3
Mon solveur de s.u.d.o.k.u marche mais trouve pas toutes les solutionsSUDOKU
Sudoku et recherche en largeur/profondeurlogiciel de SUDOKU - moteur de grilles sous VB6
Plus de sujets relatifs à : Sudoku


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR