IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Téléchargé 1 fois
Vote des utilisateurs
0 
0 
Détails
Éditeur : Olivier Cuchet
Licence : Démonstration
Mise en ligne le 26 octobre 2014
Langue : Français
Référencé dans
Navigation

Solveur mots mêlés

A partir d'un fichier "tableau.txt" contenant une grille rectangulaire de lettres et d'un fichier "mots.txt" contenant une liste de mots, le solveur trouve tous les mots dans la grille (dans les 8 directions possibles), les barre virtuellement et fournit à l'entrée standard les lettres restantes.

Le code ne comporte pas de variables externes, ce qui permet une adaptation relativement simple vers de la POO.

Les tableaux ne sont (presque pas) employés, dans un but d'efficience mémoire. Pour cette même raison, puisque les dimensions de tableaux ne peuvent être définies pendant l'exécution, le travail ne se fait pas sur des indices bidimensionnels, mais sur des pointeurs vers des données unidimensionelles.
Avatar de lautrec1
Membre actif https://www.developpez.com
Le 11/11/2014 à 10:24
Le problème à résoudre reste bien sûr identique.

La démarche pour le résoudre est différente (merci à yahiko,medinoc et diogene):

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
Charger les c lettres de la grille 
 
Pour toutes les c lettres de la grille (c=0...tailleGrille-1) 
     Pour les i directions (i=0...7) 
         Enregistrer la SousGrille sg[c,i] : séquence de caractères partant de c et rejoignant le bord de la grille dans la direction i 
 
Pour tous les mots M à trouver dans la grille (M=0....nMots) 
     Pour toutes les c lettres de la grille (c=0...tailleGrille-1) 
          Pour les i directions (i=0...7) 
               si strncmp(mot[M],SousGrille[c,i],strlen(mot))==0 
                   alors on met dans la grille les lettres composant la SousGrille à ' ' 
 
Pour toutes les c lettres de la grille (c=0...tailleGrille-1) 
      Si c<>' ', imprimer c
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
 
#define MAX_MOT 50 
#define DIM_MAX 60 
#define MAXGRILLE 1500 
 
/*TYPES*/ 
const short incr1[8]= {-1,0,1, 0,-1,1, 1,-1}; 
const short incr2[8]= { 0,1,0,-1, 1,1,-1,-1}; 
enum DIRECTION {NORD=0,EST,SUD,OUEST,NORDEST,SUDEST,SUDOUEST,NORDOUEST}; 
 
 
typedef int indice_t; 
 
typedef struct 
{ 
  char *listeCars; 
  enum DIRECTION sens; 
  indice_t indice; 
 
} SousGrille_t; 
 
typedef struct 
{ 
  SousGrille_t *y; 
} SousGrilleParCar_t; 
 
typedef struct 
{ 
  char *grille; 
  SousGrilleParCar_t *x; 
  int largeur; 
  int hauteur; 
} GrilleMotsMeles_t; 
 
 
/*PROTOTYPES*/ 
GrilleMotsMeles_t *initGrilleMotsMeles(FILE *); 
char *initCaracteres(FILE *,int *,int *); 
SousGrille_t *initElementSousGrille(char *,int,int,int,int); 
void resoudreGrille(GrilleMotsMeles_t *,FILE*); 
void afficherResultat(GrilleMotsMeles_t *); 
void assure(void *, const char *); 
 
/*SOLVEUR DE MOTS MELES 
 PRE: "tableau.txt" contient la grille de caractères 
      "mots.txt" contient un mot par ligne. Ce sont les mots dont les caractères doivent être 
		barrés dans la grille 
 POST "result.txt" contient la suite de lettre de la grille qui n'ont pas été barrées  
	(sens gauche vers droite, haut vers bas) 
*/ 
int main() 
{ 
GrilleMotsMeles_t *grillemelimelo; 
FILE* fGrille; 
FILE* fMots; 
	 
	/*redirection de la sortie standard vers RESULT.TXT*/ 
	freopen("RESULT.TXT","w",stdout); 
 
	/*initialise la grille et les structures sous-jacentes*/ 
	fGrille=fopen("tableau.txt","r"); 
	grillemelimelo=initGrilleMotsMeles(fGrille); 
 
	/*trouve les mots à chercher dans la grille et barre les lettres une fois trouvées*/ 
	fMots=fopen("mots.txt","r"); 
	resoudreGrille(grillemelimelo,fMots); 
 
	/*affiche les lettres qui n'ont pas été barrées*/ 
	afficherResultat(grillemelimelo); 
 
	return 1; 
} 
 
/*initialisation de la structure GrilleMotMeles_t à partir d'un tableau de caractères présent 
dans le fichier fichierGrille*/ 
GrilleMotsMeles_t *initGrilleMotsMeles(FILE *fichierGrille) 
{ 
GrilleMotsMeles_t *p; 
SousGrille_t *tmp; 
indice_t tailleGrille; 
int i,j; 
 
	p=(GrilleMotsMeles_t *)malloc(sizeof(GrilleMotsMeles_t)); 
    assure(p,"initGrilleMotsMeles: erreur malloc"); 
 
	/*on a besoin d'avoir tous les caractères de la grille de mots mêlés*/ 
	p->grille=initCaracteres(fichierGrille,&(p->hauteur),(&p->largeur)); 
 
	tailleGrille=p->hauteur*p->largeur; 
	 
	p->x=calloc(tailleGrille,sizeof(SousGrilleParCar_t)); 
    assure(p,"initGrilleMotsMeles: erreur calloc"); 
 
	/*chargement des données*/ 
	 
	/*pour tous les caractères de la grille...*/ 
	for(i=0;i<tailleGrille;i++) { 
 
		p->x[i].y=calloc(8,sizeof(SousGrille_t)); 
		assure(p->x[i].y,"initCaracteres:erreur calloc"); 
		 
		/*...pour les 8 directions DIR...*/ 
		for(j=0;j<8;j++) { 
		 
			/*...on charge les sous-grilles partant du caractère et allant jusqu'au bord de la grille,  
			dans la direction DIR*/ 
			tmp=initElementSousGrille(p->grille,i,p->hauteur,p->largeur,j);	   
			memcpy((p->x[i].y)+j,tmp,sizeof(SousGrille_t)); 
			free(tmp); 
		}; 
	}; 
 
	return p; 
} 
 
/*charge la grille de caractères, base de la Grille de Mots Meles*/ 
char *initCaracteres(FILE *f,int *hauteur,int *largeur) 
{ 
int j,k; 
char *p; 
char c; 
long taille; 
 
	p=calloc(MAXGRILLE+1,sizeof(char)); 
    assure(p,"initCaracteres:erreur calloc"); 
	 
	j=0; 
	taille=0; 
	*largeur=0; 
	 
	for (k=0;(c=getc(f))!=EOF; k++) 
		if (c!='\n') { 
		  j++; 
		  taille++; 
		  /*on met la lettre en majuscules*/ 
		  p[k]=toupper(c); 
		} 
		else { 
		  *largeur=j; 
		  j=0; 
		  k--; /*on ne met pas '\n' dans le tableau*/ 
		}; 
		 
	*hauteur=taille/(*largeur); 
	return p; 
} 
 
/*pour un caractère de la grille et une direction donnée, renvoie un pointeur sur une chaine égale 
à la sous-grille partant du caractère donné, dans la direction donnée, et se terminant en bord de grille*/ 
SousGrille_t *initElementSousGrille(char *grille,int i, int h, int l, int numDir) 
{ 
char tmpCar[DIM_MAX]; 
int k,increment; 
SousGrille_t *p; 
 
    p=malloc(sizeof(SousGrille_t)); 
    assure(p,"initElementSousGrille: erreur malloc"); 
     
	p->indice=i; 
    p->sens=numDir; 
	 
	/*détermination de l'incrément des indices à partir de la direction*/ 
    increment=incr1[numDir]*l+incr2[numDir]; 
	 
    k=0; 
	/* il y a au moins une lettre de la grille à charger*/ 
	/* on les mémorise, et on charge la suivante, jusqu'à ce que celle-ci dépasse le bord de la grille*/ 
	/*quand on se déplace vers la gauche de la grille, on n'enregistre pas l'élement pour lequel 
	  l'indice%largeur==largeur-1*/ 
	/*quand on se déplace vers la droite de la grille, on n'enregistre pas l'élement pour lequel 
	  l'indice%largeur==0*/ 
    do{ 
		tmpCar[k++]=grille[i]; 
		i+=increment; 
		if(incr2[numDir]>0 && i%l==0) 
			break; 
		else if(incr2[numDir]<0 && i%l==l-1) 
			break; 
 
    } while (i>=0 && i<l*h); 
    tmpCar[k]='\0'; 
 
    p->listeCars=calloc(k+1,sizeof(char)); 
    assure(p->listeCars,"initSousGrille:erreur calloc"); 
 
    strcpy(p->listeCars,tmpCar); 
	 
	return p; 
} 
 
/*pour tous les mots M de fichierMots (un mot par ligne), on va trouver la sous-grille  
(couple caractère-directio), pour lequel le début de la sous-grille égale le mot M.*/ 
void resoudreGrille(GrilleMotsMeles_t *p,FILE* fichierMots) 
{ 
char mot [MAX_MOT]; 
int i,k,dir,increment,len; 
indice_t tailleGrille; 
	 
	tailleGrille=p->largeur*p->hauteur; 
	 
	/*tant qu'il y a une ligne contenant un mot*/ 
	while ((fscanf(fichierMots,"%s\n",mot))!=EOF) { 
	 
		len=strlen(mot); 
		 
		/*on met le mot en majuscules*/ 
		for(i=0;i<len;i++) 
			mot[i]=toupper(mot[i]); 
		 
		/*on va rechercher dans pour tous les les caractères de la grille....*/ 
		for(i=0;i<tailleGrille;i++) 
			 
			/*...toutes les directions*/ 
			for(dir=0;dir<8;dir++) { 
			 
				/*test d'égalité entre le mot et le début de la listeCars*/ 
				if (0==strncmp(mot,p->x[i].y[dir].listeCars,len)) { 
				 
						/*la SousGrille_t [i,dir] égale le mot à trouver*/ 
						/*on élimine de la grille les lettres du mot trouvé, en les mettant à ' '*/ 
						increment=incr1[dir]*(p->largeur)+incr2[dir]; 
						for(k=0;k<len;k++) 
							p->grille[i+k*increment]= ' '; 
					} 
			}			 
	} 
	return; 
} 
 
void afficherResultat(GrilleMotsMeles_t *p) 
{ 
char c; 
	/*on affiche toutes les lettres de la grilles qui n'ont pas été supprimées (= différentes de ' ')*/ 
	while((c=*(p->grille++))!='\0') 
		if (c!=' ') 
			putchar(c); 
	return; 
} 
 
/*affiche un message si pointeur ptr NULL*/ 
void assure(void *ptr, const char *msg) 
{ 
  if (ptr==NULL) 
  { 
    fprintf(stdout,"\n"); 
    fprintf(stdout,msg); 
    fprintf(stdout,"\n"); 
    fflush(stdout); 
    exit(EXIT_FAILURE); 
  } 
}
Avatar de lautrec1
Membre actif https://www.developpez.com
Le 12/11/2014 à 14:26
Suite aux conseils de Sve@r et diogene :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
Charger S: ensemble toutes les c lettres de la grille 
Charger S', copie de S 
  
Pour tous les mots M à trouver dans la grille (M=0....nMots) 
     Pour toutes les c lettres de S (c=0...tailleGrille-1) 
                 si c= M[1] 
                        Pour les i directions (i=0...7) 
                                Charger la SousGrille sg[c,i] : séquence de caractères partant de c et rejoignant le bord de la grille dans la direction i      
                                si strncmp(mot[M],SousGrille[c,i],strlen(mot))==0 
                                      mot trouve=vrai; 
                                      mettre dans la grille les lettres composant la SousGrille à '\0' dans la grille S 
                                      passer au mot suivant 
  
Pour toutes les c lettres de la grille G'(c=0...tailleGrille-1) 
      Si c<>'\0 ', imprimer c
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#include <time.h> 
 
#define MAX_MOT 50 
#define DIM_MAX 60 
#define MAXGRILLE 1500 
 
/*TYPES*/ 
const short incr1[8]= {-1,0,1, 0,-1,1, 1,-1}; 
const short incr2[8]= { 0,1,0,-1, 1,1,-1,-1}; 
 
typedef int indice_t; 
typedef struct 
{ 
  char *grille; 
  char *ignore; 
  int largeur; 
  int hauteur; 
} GrilleMotsMeles_t; 
 
 
/*PROTOTYPES*/ 
GrilleMotsMeles_t *initGrilleMotsMeles(FILE *); 
void initCaracteres(FILE *,GrilleMotsMeles_t *); 
char *initElementSousGrille(GrilleMotsMeles_t *,int,int); 
void resoudreGrille(GrilleMotsMeles_t *,FILE*); 
void afficherResultat(GrilleMotsMeles_t *); 
void assure(void *, const char *); 
 
/*SOLVEUR DE MOTS MELES 
 PRE: "tableau.txt" contient la grille de caractères 
      "mots.txt" contient un mot par ligne. Ce sont les mots dont les caractères doivent être 
		barrés dans la grille 
 POST "result.txt" contient la suite de lettre de la grille qui n'ont pas été barrées  
	(sens gauche vers droite, haut vers bas) 
*/ 
int main() 
{ 
GrilleMotsMeles_t *grillemelimelo; 
FILE* fGrille; 
FILE* fMots; 
clock_t debut,fin; 
	debut=clock(); 
 
	/*redirection de la sortie standard vers RESULT.TXT*/ 
	freopen("RESULT.TXT","w",stdout); 
 
	/*initialise la grille et les structures sous-jacentes*/ 
	fGrille=fopen("tableau.txt","r"); 
	assure(fGrille,"Erreur ouverture fichier tableau.txt"); 
	grillemelimelo=initGrilleMotsMeles(fGrille); 
 
	/*trouve les mots à chercher dans la grille et barre les lettres une fois trouvées*/ 
	fMots=fopen("mots.txt","r"); 
	assure(fMots,"Erreur ouverture fichier mots.txt"); 
	resoudreGrille(grillemelimelo,fMots); 
 
	/*affiche les lettres qui n'ont pas été barrées*/ 
	afficherResultat(grillemelimelo); 
 
	fin=clock(); 
	printf("\nTemps run : %2.30f secondes\n",(double) (fin-debut)/CLOCKS_PER_SEC);		 
	 
	return 1; 
} 
 
/*initialisation de la structure GrilleMotMeles_t à partir d'un tableau de caractères présent 
dans le fichier fichierGrille*/ 
GrilleMotsMeles_t *initGrilleMotsMeles(FILE *fichierGrille) 
{ 
GrilleMotsMeles_t *pGrille; 
indice_t tailleGrille; 
int i,j; 
 
	pGrille=malloc(sizeof(GrilleMotsMeles_t)); 
    assure(pGrille,"initGrilleMotsMeles: erreur malloc"); 
 
	/*on a besoin d'avoir tous les caractères de la grille de mots mêlés*/ 
	initCaracteres(fichierGrille,pGrille); 
 
	pGrille->ignore=calloc(MAXGRILLE+1,sizeof(char)); 
    assure(pGrille->ignore,"initCaracteres:erreur calloc"); 
 
	strcpy(pGrille->ignore,pGrille->grille);	 
	return pGrille; 
} 
 
/*charge la grille de caractères, base de la Grille de Mots Meles*/ 
 void initCaracteres(FILE *f,GrilleMotsMeles_t *pGrille) 
{ 
int j,k; 
char c; 
long taille; 
 
	pGrille->grille=calloc(MAXGRILLE+1,sizeof(char)); 
    assure(pGrille->grille,"initCaracteres:erreur calloc"); 
	 
	j=0; 
	taille=0; 
	pGrille->largeur=0; 
	 
	for (k=0;(c=getc(f))!=EOF; k++) 
		if (c!='\n') { 
		  j++; 
		  taille++; 
		  /*on met la lettre en majuscules*/ 
		  pGrille->grille[k]=toupper(c); 
		} 
		else { 
		  pGrille->largeur=j; 
		  j=0; 
		  k--; /*on ne met pas '\n' dans le tableau*/ 
		}; 
		 
	pGrille->hauteur = taille/pGrille->largeur; 
 
	return; 
} 
 
/*pour un caractère de la grille et une direction donnée, renvoie un pointeur sur une chaine égale 
à la sous-grille partant du caractère donné, dans la direction donnée, et se terminant en bord de grille*/ 
char *initElementSousGrille(GrilleMotsMeles_t *pGrille,int point, int numDir) 
{ 
char tmpCar[DIM_MAX]; 
int i,k,increment; 
char *pReturnValue; 
     
	/*détermination de l'incrément des indices à partir de la direction*/ 
    increment=incr1[numDir]*pGrille->largeur+incr2[numDir]; 
	 
    k=0; 
	i=point; 
	/* il y a au moins une lettre de la grille à charger*/ 
	/* on les mémorise, et on charge la suivante, jusqu'à ce que celle-ci dépasse le bord de la grille*/ 
	/*quand on se déplace vers la gauche de la grille, on n'enregistre pas l'élement pour lequel 
	  l'indice%largeur==largeur-1*/ 
	/*quand on se déplace vers la droite de la grille, on n'enregistre pas l'élement pour lequel 
	  l'indice%largeur==0*/ 
    do{ 
		tmpCar[k++]=pGrille->grille[i]; 
		i+=increment; 
		if(incr2[numDir]>0 && i%pGrille->largeur==0) 
			break; 
		else if(incr2[numDir]<0 && i%pGrille->largeur==pGrille->largeur-1) 
			break; 
 
    } while (i>=0 && i<pGrille->largeur*pGrille->hauteur); 
    tmpCar[k]='\0'; 
 
    pReturnValue=calloc(k+1,sizeof(char)); 
    assure(pReturnValue,"initSousGrille:erreur calloc"); 
 
    strcpy(pReturnValue,tmpCar); 
 
	return; 
} 
 
/*pour tous les mots M de fichierMots (un mot par ligne), on va trouver la sous-grille  
(couple caractère-direction), pour lequel le début de la sous-grille égale le mot M.*/ 
void resoudreGrille(GrilleMotsMeles_t *pGrille,FILE* fichierMots) 
{ 
char mot [MAX_MOT]; 
char *pTmp; 
int i,k,dir,increment,len; 
indice_t tailleGrille; 
int motTrouve; 
	 
	tailleGrille=(pGrille->largeur)*(pGrille->hauteur); 
	 
	/*tant qu'il y a une ligne contenant un mot*/ 
	while ((fscanf(fichierMots,"%s\n",mot))!=EOF) { 
	 
		len=strlen(mot); 
 
		/*on met le mot en majuscules*/ 
		for(i=0;i<len;i++) mot[i]=toupper(mot[i]); 
		 
		motTrouve=0; 
			 
		/*on va rechercher dans pour tous les caractères de la grille....*/ 
		for(i=0;i<tailleGrille;i++) { 
			 
			/* si le caractères de la grille et la première lettre du mot correspondent*/ 
			if(mot[0]==pGrille->grille[i]) 
			 
				/*...toutes les directions*/ 
				for(dir=0;dir<8;dir++){ 
				 
					pTmp=initElementSousGrille(pGrille,i,dir); 
 
					/*test d'égalité entre le mot et le début de la listeCars*/ 
					if (0==strncmp(mot,pTmp,len)) { 
 
							/*la SousGrille_t [i,dir] égale le mot à trouver*/ 
							motTrouve=1; 
							 
							/*on élimine de la grille les lettres du mot trouvé, en les mettant à ' '*/ 
							increment=incr1[dir]*(pGrille->largeur)+incr2[dir]; 
							for(k=0;k<len;k++) pGrille->ignore[i+k*increment]= '\0'; 
							 
							break; 
						}; 
					free(pTmp); 
				} 
			if (motTrouve) break; 
			 
		} 
	} 
	return; 
} 
 
void afficherResultat(GrilleMotsMeles_t *p) 
{ 
	int i; 
	int taille = p->largeur*p->hauteur; 
	/*on affiche toutes les lettres de la grilles dont ignore sont encore égales à 0*/ 
	for(i=0; i<taille;i++) 
	 if(p->ignore[i]) putchar(p->grille[i]); 
} 
 
/*affiche un message si pointeur ptr NULL*/ 
void assure(void *ptr, const char *msg) 
{ 
  if (ptr==NULL) 
  { 
    fprintf(stdout,"\n"); 
    fprintf(stdout,msg); 
    fprintf(stdout,"\n"); 
    fflush(stdout); 
    exit(EXIT_FAILURE); 
  } 
}
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.