Un algo qui marche, sauf à la fin.
eaatmaan
Messages postés
1
Statut
Membre
-
eaatmaan -
eaatmaan -
Bonjour,
J'ai fait un petit programme en C pour la résolution des sudoku.
Je sais que je n'innove pas mais malgré tout ce que j'ai pu lire ici, j'ai une erreur que je n'arrive pas à résoudre:
J'ai voulu travailler sur différentes étapes de difficultés.
1: Les sudokus simples où on peux remplir toutes les cases en regardant simplement les lignes/colonne/carrés où une seule valeur est manquante. (Ici, tout fonctionne)
2: Les sudokus un peu plus difficiles où des plusieurs valeurs sont manquantes et où je regarde si une valeur possible est seule dans une ligne/colonne/carré.
Et là, tout se passe bien jusqu'à ce qu'il reste 5 ou 6 cases, dès lors mon algo me met plusiseurs 7,8 ou 9 dans une ligne et une colonne...
Mon sudoku est stocké dans un tableau de 9*9 cases de type cellule comprenant la valeur et un tableau de 9 booléens permettant de stocker les valeurs possibles.
PS: dans le menu, la lettre v permet de voir les possibilités d'une case en particulier.
Voici mon code, si une âme généreuse à un peu de temps je lui en serait fort reconnaissant!
J'ai fait un petit programme en C pour la résolution des sudoku.
Je sais que je n'innove pas mais malgré tout ce que j'ai pu lire ici, j'ai une erreur que je n'arrive pas à résoudre:
J'ai voulu travailler sur différentes étapes de difficultés.
1: Les sudokus simples où on peux remplir toutes les cases en regardant simplement les lignes/colonne/carrés où une seule valeur est manquante. (Ici, tout fonctionne)
2: Les sudokus un peu plus difficiles où des plusieurs valeurs sont manquantes et où je regarde si une valeur possible est seule dans une ligne/colonne/carré.
Et là, tout se passe bien jusqu'à ce qu'il reste 5 ou 6 cases, dès lors mon algo me met plusiseurs 7,8 ou 9 dans une ligne et une colonne...
Mon sudoku est stocké dans un tableau de 9*9 cases de type cellule comprenant la valeur et un tableau de 9 booléens permettant de stocker les valeurs possibles.
PS: dans le menu, la lettre v permet de voir les possibilités d'une case en particulier.
Voici mon code, si une âme généreuse à un peu de temps je lui en serait fort reconnaissant!
#include <stdio.h>
typedef struct Cellule //Structure Cellule
{//Definition d'une case du tableau.
int val; //une case valeur.
int sol[9]; //Un tableau contenant les possibilités.
} cellule; //type cellule.
void initialiser_val(); //0 dans toutes les cases.
void initialiser_sol(); //1 dans toutes les cases du tableau solution.
void menu(); //Le menu d'actions.
void afficher(); //Affiche simplement le tableau.
void remplir(); //Remplis des cases du tableau.
void solution(); //Tente de remplir les cases vides.
void no_sol(int i, int j); //Supprime toutes les solution dans la case i.j.
void ellim_poss(); //Supprime les valeurs impossibes.
void sol_unique_poss(); //Affecte la valeur si unique solution.
void voir(); //Donne la valeur et les possibilités d'une case.
int sol_mul_car (int lig, int col, int valm);
int sol_mul_lig (int ligne, int valm);
int sol_mul_col (int colonne, int valm);
void ellim_poss_multiple();
cellule Sudoku[9][9]; //Le tableau en variable globale.
int main (int argc, char **argv)
{
initialiser_val();
initialiser_sol();
menu();
return 0;
}
void initialiser_val()
{
int i,j;
for (i=0; i<9; i++)
{//Parcours de lignes.
for (j=0; j<9; j++)
{//Parcours de collones.
(Sudoku[i][j]).val = 0;
}
}
}
void initialiser_sol()
{
int i,j,k;
for (i=0; i<9; i++)
{//Parcours de lignes.
for (j=0; j<9; j++)
{//Parcours de collones.
for (k=0; k<9; k++)
{
(Sudoku[i][j]).sol[k] = 1;
}
}
}
}
void menu()
{
char commande = 0;
int cont = 1;
do
{
printf("r pour remplir; a pour afficher; s pour la solution; q pour quitter;");
scanf("%c", &commande);
switch (commande)
{
case 'r':
{
initialiser_sol();
do //---------------------------------------------------------------------------------------//
{ //
remplir(); //
printf("\nContinuer à remplir? o/n\t"); //Boucle de remplissage de tableau.
scanf("%i", &cont); //
printf("\n"); //
} while (cont); //---------------------------------------------------------------------------------------//
break;
}
case 'a':
{
afficher();
break;
}
case 'q':
{
break;
}
case 's':
{
/*changement = solution();
if (changement == 0)
{
printf("Pas de changement effectués\n");
}*/
solution();
break;
}
case 'v':
{
voir();
break;
}
}
getchar();
} while (commande != 'q');
}
void afficher()
{
int i,j;
printf("\n");
for (i=0; i<9; i++)
{//Parcours de lignes.
for (j=0; j<9; j++)
{//Parcours de collones.
if (Sudoku[i][j].val != 0)
{//Si la case n'est pas vide.
printf(" %i ", Sudoku[i][j].val); //On affiche la valeur.
}
else
{//Si la case est vide.
printf(" . "); //On affiche un point.
}
if ((j+1)%3 == 0)
{//3eme ou 6eme colonne.
printf(" ");
}
else
{//Autres colonnes.
printf("|");
}
}
printf("\n");
if ((i+1)%3 == 0)
{//Lignes 3 et 6, un espace.
printf("\n");
}
}
}
void remplir(){
int i,j,k;
printf("Quelle ligne?\t");
scanf("%i", &i); //On choisit la ligne.
printf("Quelle colonne?\t");
scanf("%i", &j); //On choisit la colonne.
printf("Quelle valeur?\t");
scanf("%i", &k); //On choisit la valeur.
if (i<10 && i>0 && j<10 && j>0 && k<10 && k>=0) //Si on est bien entre 1 et 9 pour i,j et entre 0 et 9 pour k.
{
Sudoku[i-1][j-1].val = k; //On affecte k à la valeur de la case.
}
else
printf("Mauvaises valeurs\n");
}
void no_sol(int i, int j)
{
int a;
for (a=0; a<9; a++)
{
(Sudoku[i][j]).sol[a]=0; //Toutes les possibilités sont mise à 0.
}
}
void solution()
{
ellim_poss();
sol_unique_poss();
ellim_poss_multiple();
sol_unique_poss();
}
void ellim_poss()
{
int i,j; //Des variables de parcours global.
int a,b; //Des varaibles de parcours internes.
int var; //Une variable de stockage.
for (i=0; i<9; i++)
{//Parcours des lignes.
for (j=0; j<9; j++)
{//Parcours des colonnes.
if (Sudoku[i][j].val != 0)
{//Si la case n'est pas vide.
no_sol(i,j); //On supprime toutes les possibilités de changements.
var = Sudoku[i][j].val;
for (a=0; a<9; a++) //----------------------------------------------------------//
{ //
Sudoku[a][j].sol[var-1] = 0; // On enlève la valeur dans la ligne et dans la colonne.
Sudoku[i][a].sol[var-1] = 0; //
} //----------------------------------------------------------//
for (a=0; a<3; a++)
{//Parcours des lignes du carre de 3*3
for (b=0; b<3; b++)
{//Parcours des colonnes du carre de 3*3
Sudoku[(3*(i/3))+((i+a)%3)][(3*(j/3))+((j+b)%3)].sol[var-1] = 0; //Enleve poss carre.
}
}
}
}
}
}
void sol_unique_poss()
{
int i,j;
int a;
int s, temp;
for (i=0; i<9; i++)
{//Parcours des lignes
for (j=0; j<9; j++)
{//Parcours des colonnes.
s = 0; temp = 0;
for (a=0; a<9; a++)
{//Parcours des possibilites.
s += Sudoku[i][j].sol[a]; //Somme des booleens de possibilites.
if (Sudoku[i][j].sol[a])
{//Si la S[i][j].sol[a] n'est pas nulle.
temp = a; //temp garde l'indice.
}
}
if (s == 1)
{//Si il n'y a qu'une seule possibilité.
Sudoku[i][j].val = temp+1; //On affecte la seule valeur possible.
}
}
}
}
void ellim_poss_multiple()
{
int i,j,k;
for (i=0; i<9; i++)
{//Parcours des lignes.
for (j=0; j<9; j++)
{//Parcours des colonnes.
if (Sudoku[i][j].val == 0)
{//Si la case est vide.
for (k=0; k<9; k++)
{//Parcours des solutions
if (Sudoku[i][j].sol[k] == 1)
{//k+1 est une valeur possible.
if (sol_mul_lig(i,k) || sol_mul_col(j,k) || sol_mul_car(i,j,k) )
{//Si valeur possible une seule fois
Sudoku[i][j].val = k+1;
no_sol(i,j);
solution();
}
}
}
}
}
}
}
int sol_mul_lig(int ligne, int valm)
{
int j, retour = 0;
for (j=0; j<9; j++)
{//Parcours des cases de la lignes.
if (Sudoku[ligne][j].val == 0)
{//Si une case de la ligne est vide.
if (Sudoku[ligne][j].sol[valm] == 1)
{//Si dans cette case vide, la valeur est possible.
retour ++;
}
}
}
return (retour == 1);
}
int sol_mul_col(int colonne, int valm)
{
int i, retour = 0;
for (i=0; i<9; i++)
{//Parcours des cases de la colonne.
if (Sudoku[i][colonne].val == 0)
{//Si une case de la ligne est vide.
if (Sudoku[i][colonne].sol[valm] == 1)
{//Si dans cette case vide, la valeur est possible.
retour ++;
}
}
}
return (retour == 1);
}
int sol_mul_car(int lig, int col, int valm)
{
int a, b, retour = 0;
for (a=0; a<3; a++)
{//Parcours des lignes du carre de 3*3
for (b=0; b<3; b++)
{//Parcours des colonnes du carre de 3*3
if ((Sudoku[(3*(lig/3))+((lig+a)%3)][(3*(col/3))+((col+b)%3)]).val == 0)
{//Si la case est vide
if ((Sudoku[(3*(lig/3))+((lig+a)%3)][(3*(col/3))+((col+b)%3)]).sol[valm] == 1)
{//La valeur est possible.
retour ++;
}
}
}
}
return (retour == 1);
}
void voir()
{ ellim_poss();
int i,j,k;
printf("Quelle ligne? \t");
scanf("%i",&i);
printf("Quelle colonne? \t");
scanf("%i",&j);
printf("\n Valeur: %i\t Possibilites:", Sudoku[i-1][j-1].val);
for (k=0; k<9; k++)
{
if (Sudoku[i-1][j-1].sol[k] == 1)
{
printf("%i ", k+1);
}
}
printf("\n");
}
A voir également:
- Un algo qui marche, sauf à la fin.
- Fin des zfe - Guide
- Reconsidérer le traitement de vos informations à des fins publicitaires - Accueil - Réseaux sociaux
- Fin de la 4g en france - Accueil - Guide opérateurs et forfaits
- Fin numericable - Accueil - Box & Connexion Internet
- Fin de fruitz - Accueil - Applications & Logiciels