Rapport Suguru 1.0
Dev-linux
code.c
Go to the documentation of this file.
1
10#include <stdlib.h>
11#include <stdio.h>
12#include <string.h>
13
19typedef int cpt;
20void afficher_grille(int **grille, int h, int w);
21
22//############################################ Strucuture pour les choix au fur et à mesure de la résolution ############################################
23
29typedef struct {
30 int indice[2];
31 int tab[6];
32 int nombre;
33} choix;
34
35//############################################ Déplacements: haut, bas, gauche, droite ############################################
36int dx[] = {-1, 1, 0, 0};
37int dy[] = {0, 0, -1, 1};
38
39//############################################ Détection des cages et attribution d'identifiants uniques ############################################
40
50void creer_cages_identifiants(char **cage, int h, int w, int **cage_identifiant) {
51 int prochain_id = 0;
52 cpt i,j;
53 for (i = 0; i < h; i++) {
54 for (j = 0; j < w; j++) {
55 cage_identifiant[i][j] = -1;
56 }
57 }
58 cpt a,b,c,d,e;
59 for (a = 0; a < h; a++) {
60 for (b = 0; b < w; b++) {
61 if (cage_identifiant[a][b] == -1) {
62 char cage_type = cage[a][b];
63 cage_identifiant[a][b] = prochain_id;
64
65 int **queue = malloc(h * w * sizeof(int*));
66 for (c = 0; c < h * w; c++) {
67 queue[c] = malloc(2 * sizeof(int));
68 }
69
70 int front = 0, rear = 0;
71 queue[rear][0] = a;
72 queue[rear++][1] = b;
73
74 while (front < rear) {
75 int x = queue[front][0], y = queue[front++][1];
76
77 for (int d = 0; d < 4; d++) {
78 int nx = x + dx[d], ny = y + dy[d];
79
80 if (nx >= 0 && nx < h && ny >= 0 && ny < w &&
81 cage_identifiant[nx][ny] == -1 && cage[nx][ny] == cage_type) {
82 cage_identifiant[nx][ny] = prochain_id;
83 queue[rear][0] = nx;
84 queue[rear++][1] = ny;
85 }
86 }
87 }
88
89 for (e = 0; e < h * w; e++) {
90 free(queue[e]);
91 }
92 free(queue);
93
94 prochain_id++;
95 }
96 }
97 }
98}
99
100//############################################ Classification des indices par cages ############################################
101
113void classifier_indices_par_cages(int **cage_identifiant, int h, int w, int ****tab, int *nombre_cages, int **cage_sizes) {
114 int max_cage_id = 0;
115 cpt i,j;
116 for (i = 0; i < h; i++) {
117 for (j = 0; j < w; j++) {
118 if (cage_identifiant[i][j] > max_cage_id) {
119 max_cage_id = cage_identifiant[i][j];
120 }
121 }
122 }
123 *nombre_cages = max_cage_id + 1;
124
125 *cage_sizes = malloc((*nombre_cages) * sizeof(int));
126 cpt k;
127 for (k = 0; k < *nombre_cages; k++) {
128 (*cage_sizes)[k] = 0;
129 }
130 cpt l,m;
131 for (l = 0; l < h; l++) {
132 for (m = 0; m < w; m++) {
133 int cage_id = cage_identifiant[l][m];
134 (*cage_sizes)[cage_id]++;
135 }
136 }
137
138 *tab = malloc((*nombre_cages) * sizeof(int**));
139 cpt n,o;
140 for (n = 0; n < *nombre_cages; n++) {
141 (*tab)[n] = malloc((*cage_sizes)[n] * sizeof(int*));
142 for (o = 0; o < (*cage_sizes)[n]; o++) {
143 (*tab)[n][o] = malloc(2 * sizeof(int));
144 }
145 }
146
147 int *cage_counter = malloc(*nombre_cages * sizeof(int));
148 cpt p;
149 for (p = 0; p < *nombre_cages; p++) {
150 cage_counter[p] = 0;
151 }
152 cpt q,r;
153 for (q = 0; q < h; q++) {
154 for (r = 0; r < w; r++) {
155 int cage_id = cage_identifiant[q][r];
156 (*tab)[cage_id][cage_counter[cage_id]][0] = q;
157 (*tab)[cage_id][cage_counter[cage_id]][1] = r;
158 cage_counter[cage_id]++;
159 }
160 }
161
162 free(cage_counter);
163}
164
165//############################################## Possibilité de remplissage pour une case donnée ##############################################
166
181void possible(int ligne, int colonne, int x, int y, int cage[], int** grille, int*** tab, int** cage_identifiant, int possibilite[]) {
182 if (grille[x][y] == 0) {
183 cpt i;
184 for (i = 0; i < 6; i++) {
185 possibilite[i] = i + 1;
186 }
187 cpt j, k;
188 for (j = -1; j < 2; j++) {
189 for (k = -1; k < 2; k++) {
190 if(x + j < ligne && y + k < colonne && x+j>-1 && y+k>-1){
191 int val = grille[x + j][y + k];
192 if (val < 7) {
193 possibilite[val - 1] = 0;
194 }
195 }
196 }
197 }
198 int tailleCage = cage[cage_identifiant[x][y]];
199 cpt l;
200 for (l = tailleCage; l < 6; l++) {
201 possibilite[l] = 0;
202 }
203 cpt m;
204 for (m = 0; m < tailleCage; m++) {
205 int a = tab[cage_identifiant[x][y]][m][0];
206 int b = tab[cage_identifiant[x][y]][m][1];
207 int val = grille[a][b];
208 if (val < 7) {
209 possibilite[val - 1] = 0;
210 }
211 }
212 }
213 else {
214 cpt i;
215 for (i = 0; i < 6; i++) {
216 possibilite[i] = 0;
217 }
218 }
219}
220
221//############################################## Résolution du suguru ##############################################
222
242int resoudre(int ligne, int colonne, int x, int y, choix choisi[], int resolu[][2], int cage[], int** grille, int*** tab, int** cage_identifiant, int numero, int caseRempli, int decision) {
243 if (caseRempli == ligne * colonne) {
244 return 0;
245 }
246 int possibilite[6]={0};
247 possible(ligne, colonne, x, y, cage, grille,tab,cage_identifiant,possibilite);
248 int nombrePossibilite = 0;
249 int valeur;
250 cpt i;
251 for (i = 0; i < 6; i++) {
252 if (possibilite[i] != 0) {
253 nombrePossibilite++;
254 valeur = possibilite[i];
255 }
256 }
257 if (nombrePossibilite == 0) {
258 cpt i;
259 for(i=numero-1;resolu[i][0]!=choisi[decision-1].indice[0] && resolu[i][1]!=choisi[decision-1].indice[1];i--){
260 grille[resolu[i][0]][resolu[i][1]]=0;
261 caseRempli--;
262 }
263 int nouvellePossibilite[6]={0};
264 possible(ligne, colonne, choisi[decision-1].indice[0], choisi[decision-1].indice[1], cage, grille,tab,cage_identifiant,nouvellePossibilite);
265 int nouveauNombrePossibilite = 0;
266 cpt j;
267 for (j = 0; j < 6; j++) {
268 if (nouvellePossibilite[j] != 0) {
269 nouveauNombrePossibilite++;
270 }
271 }
272 if(choisi[decision-1].nombre!=nouveauNombrePossibilite){
273 int nouvelleValeur=0;
274 cpt j,k;
275 for(j=0;j<6 && nouvelleValeur==0;j++){
276 if(nouvellePossibilite[j]!=0){
277 int trouve=0;
278 for(k=0;k<choisi[decision-1].nombre && trouve==0;k++){
279 if(choisi[decision-1].tab[k]==nouvellePossibilite[j]){
280 trouve=1;
281 }
282 }
283 if(trouve==0){
284 nouvelleValeur=nouvellePossibilite[j];
285 }
286 }
287 }
288 grille[choisi[decision-1].indice[0]][choisi[decision-1].indice[1]]=nouvelleValeur;
289 choisi[decision-1].tab[choisi[decision-1].nombre]=nouvelleValeur;
290 choisi[decision-1].nombre++;
291 cpt l;
292 int a, b;
293 int x=choisi[decision-1].indice[0],y=choisi[decision-1].indice[1];
294 int trouve = 0;
295 for (l = 0; l < cage[cage_identifiant[x][y]] && trouve == 0; l++) {
296 int tmp_x = tab[cage_identifiant[x][y]][l][0];
297 int tmp_y = tab[cage_identifiant[x][y]][l][1];
298 if (grille[tmp_x][tmp_y] == 0) {
299 a = tmp_x;
300 b = tmp_y;
301 trouve = 1;
302 }
303 }
304 if (trouve == 0) {
305 cpt k, l, m;
306 for (k = 0; k < 20 && trouve == 0; k++) {
307 for (l = -1 - k; l < 1 + k && trouve == 0; l++) {
308 for (m = -1 - k; m < 1 + k && trouve == 0; m++) {
309 if (x + l < ligne && y + m < colonne && x+l>-1 && y+m>-1 && grille[x + l][y + m] == 0) {
310 a = x + l;
311 b = y + m;
312 trouve = 1;
313 }
314 }
315 }
316 }
317 }
318 resoudre(ligne, colonne, a, b, choisi, resolu, cage, grille, tab, cage_identifiant, i+1, caseRempli, decision);
319 }
320 else{
321 int nouvellePossibilite[6]={0};
322 possible(ligne, colonne, choisi[decision-2].indice[0], choisi[decision-2].indice[1], cage, grille,tab,cage_identifiant,nouvellePossibilite);
323 int nouveauNombrePossibilite = 0;
324 cpt j;
325 for (j = 0; j < 6; j++) {
326 if (nouvellePossibilite[j] != 0) {
327 nouveauNombrePossibilite++;
328 }
329 }
330 cpt k=i-1;
331 j=2;
332 while(nouveauNombrePossibilite==choisi[decision-j].nombre){
333 for(;resolu[k][0]!=choisi[decision-j].indice[0] && resolu[k][1]!=choisi[decision-j].indice[1];k--){
334 grille[resolu[k][0]][resolu[k][1]]=0;
335 caseRempli--;
336 }
337 choisi[decision-j].nombre=0;
338 choisi[decision-j].indice[0]=0;
339 choisi[decision-j].indice[1]=0;
340 cpt m;
341 for(m=0;choisi[decision-j].tab[m]!=0;m++){
342 choisi[decision-j].tab[m]=0;
343 }
344 j++;
345 int nouvellePossibilite[6]={0};
346 possible(ligne, colonne, choisi[decision-j].indice[0], choisi[decision-j].indice[1], cage, grille,tab,cage_identifiant,nouvellePossibilite);
347 int nouveauNombrePossibilite = 0;
348 cpt l;
349 for (l = 0; l < 6; l++) {
350 if (nouvellePossibilite[l] != 0) {
351 nouveauNombrePossibilite++;
352 }
353 }
354 }
355 int nouvelleValeur=0;
356 cpt m,n;
357 for(m=0;m<6 && nouvelleValeur==0;m++){
358 if(nouvellePossibilite[m]!=0){
359 int trouve=0;
360 for(n=0;n<choisi[decision-j+1].nombre && trouve==0;n++){
361 if(choisi[decision-j+1].tab[n]==nouvellePossibilite[m]){
362 trouve=1;
363 }
364 }
365 if(trouve==0){
366 nouvelleValeur=nouvellePossibilite[m];
367 }
368 }
369 }
370 grille[choisi[decision-j+1].indice[0]][choisi[decision-j+1].indice[1]]=nouvelleValeur;
371 choisi[decision-j+1].tab[choisi[decision-j+1].nombre]=nouvelleValeur;
372 choisi[decision-j+1].nombre++;
373 cpt l;
374 int a, b;
375 int x=choisi[decision-j+1].indice[0],y=choisi[decision-j+1].indice[1];
376 int trouve = 0;
377 for (l = 0; l < cage[cage_identifiant[x][y]] && trouve == 0; l++) {
378 int tmp_x = tab[cage_identifiant[x][y]][l][0];
379 int tmp_y = tab[cage_identifiant[x][y]][l][1];
380 if (grille[tmp_x][tmp_y] == 0) {
381 a = tmp_x;
382 b = tmp_y;
383 trouve = 1;
384 }
385 }
386 if (trouve == 0) {
387 cpt k, l, m;
388 for (k = 0; k < 20 && trouve == 0; k++) {
389 for (l = -1 - k; l < 1 + k && trouve == 0; l++) {
390 for (m = -1 - k; m < 1 + k && trouve == 0; m++) {
391 if (x + l < ligne && y + m < colonne && x+l>-1 && y+m>-1 && grille[x + l][y + m] == 0) {
392 a = x + l;
393 b = y + m;
394 trouve = 1;
395 }
396 }
397 }
398 }
399 }
400 resoudre(ligne, colonne, a, b, choisi, resolu, cage, grille, tab, cage_identifiant, k+1, caseRempli, decision-j+1);
401 }
402 }
403 else if (nombrePossibilite == 1) {
404 grille[x][y] = valeur;
405 resolu[numero][0]=x;
406 resolu[numero][1]=y;
407 cpt j;
408 int a, b;
409 int trouve = 0;
410 for (j = 0; j < cage[cage_identifiant[x][y]] && trouve == 0; j++) {
411 int tmp_x = tab[cage_identifiant[x][y]][j][0];
412 int tmp_y = tab[cage_identifiant[x][y]][j][1];
413 if (grille[tmp_x][tmp_y] == 0) {
414 a = tmp_x;
415 b = tmp_y;
416 trouve = 1;
417 }
418 }
419 if (trouve == 0) {
420 cpt k, l, m;
421 for (k = 0; k < 20 && trouve == 0; k++) {
422 for (l = -1 - k; l < 1 + k && trouve == 0; l++) {
423 for (m = -1 - k; m < 1 + k && trouve == 0; m++) {
424 if (x + l < ligne && y + m < colonne && x+l>-1 && y+m>-1 && grille[x + l][y + m] == 0) {
425 a = x + l;
426 b = y + m;
427 trouve = 1;
428 }
429 }
430 }
431 }
432 }
433 resoudre(ligne, colonne, a, b, choisi, resolu, cage, grille, tab, cage_identifiant, numero + 1, caseRempli + 1, decision);
434 }
435 else {
436 grille[x][y] = valeur;
437 resolu[numero][0]=x;
438 resolu[numero][1]=y;
439 choisi[decision].tab[0] = valeur;
440 choisi[decision].tab[1] = 0;
441 choisi[decision].indice[0] = x;
442 choisi[decision].indice[1] = y;
443 choisi[decision].nombre=1;
444 cpt j;
445 int a, b;
446 int trouve = 0;
447 for (j = 0; j < cage[cage_identifiant[x][y]] && trouve == 0; j++) {
448 int tmp_x = tab[cage_identifiant[x][y]][j][0];
449 int tmp_y = tab[cage_identifiant[x][y]][j][1];
450 if (grille[tmp_x][tmp_y] == 0) {
451 a = tmp_x;
452 b = tmp_y;
453 trouve = 1;
454 }
455 }
456 if (trouve == 0) {
457 cpt k, l, m;
458 for (k = 0; k < 20 && trouve == 0; k++) {
459 for (l = -1 - k; l < 1 + k && trouve == 0; l++) {
460 for (m = -1 - k; m < 1 + k && trouve == 0; m++) {
461 if (x + l < ligne && y + m < colonne && x+l>-1 && y+m>-1 && grille[x + l][y + m] == 0) {
462 a = x + l;
463 b = y + m;
464 trouve = 1;
465 }
466 }
467 }
468 }
469 }
470 resoudre(ligne, colonne, a, b, choisi, resolu, cage, grille, tab, cage_identifiant, numero + 1, caseRempli + 1, decision + 1);
471 }
472 return 0;
473}
474
475//############################################ Affichage de la grille ############################################
476
485void afficher_grille(int **grille, int h, int w){
486 cpt i,j;
487 for(i=0;i<h;i++){
488 for(j=0;j<w;j++){
489 printf("%d",grille[i][j]);
490 }
491 printf("\n");
492 }
493}
494
495//############################################ Affichage des indices classés par cage ############################################
496
505void afficher_indices_par_cages(int ***tab, int nombre_cages, int *cage_sizes) {
506 printf("\nIndices classés par cages :\n");
507 cpt i,j;
508 for (i = 0; i < nombre_cages; i++) {
509 printf("Cage %d:\n", i);
510 for (j = 0; j < cage_sizes[i]; j++) {
511 printf(" (%d, %d)\n", tab[i][j][0], tab[i][j][1]);
512 }
513 }
514}
515
516//############################################ Affichage des identifiants de cage ############################################
517
526void afficher_cages(int **cage_identifiant, int h, int w) {
527 printf("\nIdentifiants des cages :\n");
528 cpt i,j;
529 for (i = 0; i < h; i++) {
530 for (j = 0; j < w; j++) {
531 printf("%d ", cage_identifiant[i][j]);
532 }
533 printf("\n");
534 }
535}
536
537int main() {
538 int w, h; //Dimension de la grille
539 scanf("%d%d", &w, &h); fgetc(stdin);
540
541//############################################ Création des tableaux à 2 dimensions ############################################
542
543 char **cage = malloc(sizeof(char*) * h); //Contient les lettres des cages de la grille de suguru
544 int **cage_identifiant = malloc(sizeof(int*) * h); //Contient les numéros des cages de la grille de suguru
545 int ** grille=malloc(sizeof(int*)*h); //Contient la grille de suguru
546 cpt i;
547 for (i = 0; i < h; i++) {
548 cage[i] = malloc(sizeof(char) * w);
549 cage_identifiant[i] = malloc(sizeof(int) * w);
550 grille[i]=malloc(sizeof(int)*w);
551 }
552
553//############################################ Remplissage des tableaux à 2 dimensions ############################################
554 cpt j,k;
555 for (j = 0; j < h; j++) {
556 char line[60];
557 scanf("%[^\n]", line); fgetc(stdin);
558 for (k= 0; k < w * 3; k += 3) {
559 cage[j][k / 3] = line[k];
560 if(line[k+1]!='.'){
561 grille[j][k/3]=line[k+1]-'0';
562 }
563 else{
564 grille[j][k/3]=0;
565 }
566 }
567 }
568
569//############################################ Création et remplissage des tableaux concernant les cages ############################################
570
571 creer_cages_identifiants(cage, h, w, cage_identifiant);
572 int ***tab;
573 int nombre_cages;
574 int *cage_sizes;
575 classifier_indices_par_cages(cage_identifiant, h, w, &tab, &nombre_cages, &cage_sizes);
576
577//############################################ Affichages ############################################
578
579 /*afficher_grille(grille,h,w);
580 afficher_cages(cage_identifiant, h, w);
581 afficher_indices_par_cages(tab, nombre_cages, cage_sizes);*/
582
583//############################################ Test appel à la fonction possible ############################################
584
585 /*int possibilite[6]={0};
586 possible(h,w,1,0,cage_sizes,grille,tab,cage_identifiant,possibilite);
587
588 cpt l;
589 printf("Les différents chiffres possibles pour l'indice (1,0): ");
590 for(l=0;l<6;l++){
591 printf("%d, ",possibilite[i]);
592 }
593 puts("");*/
594
595//############################################ Résolution du suguru ############################################
596
597 choix decision[100];
598 int casePrecedente[400][2];
599 int caseRempli=0;
600 cpt m,n;
601 for(m=0;m<h;m++){
602 for(n=0;n<w;n++){
603 if(grille[m][n]!=0){
604 caseRempli++;
605 }
606 }
607 }
608 resoudre(h,w,0,0,decision,casePrecedente,cage_sizes,grille,tab,cage_identifiant,0,caseRempli,0);
609 afficher_grille(grille,h,w);
610
611//############################################ Libération de la mémoire allouée ############################################
612
613 cpt o,p;
614 for (o = 0; o < nombre_cages; o++) {
615 for (p = 0; p < cage_sizes[o]; p++) {
616 free(tab[o][p]);
617 }
618 free(tab[o]);
619 }
620 free(tab);
621 free(cage_sizes);
622 cpt q;
623 for (q = 0; q < h; q++) {
624 free(cage[q]);
625 free(cage_identifiant[q]);
626 free(grille[q]);
627 }
628 free(cage);
629 free(cage_identifiant);
630 free(grille);
631
632 return 0;
633}
634
635
int resoudre(int ligne, int colonne, int x, int y, choix choisi[], int resolu[][2], int cage[], int **grille, int ***tab, int **cage_identifiant, int numero, int caseRempli, int decision)
complète la grille de suguru
Definition: code.c:242
void afficher_grille(int **grille, int h, int w)
affiche la grille
Definition: code.c:485
int dx[]
Definition: code.c:36
void classifier_indices_par_cages(int **cage_identifiant, int h, int w, int ****tab, int *nombre_cages, int **cage_sizes)
crée un tableau rangé par indice de cages avec tout les indices des cases présents dans la cage
Definition: code.c:113
void creer_cages_identifiants(char **cage, int h, int w, int **cage_identifiant)
crée une grille rempli avec les numéros de cages à tous les indices
Definition: code.c:50
void possible(int ligne, int colonne, int x, int y, int cage[], int **grille, int ***tab, int **cage_identifiant, int possibilite[])
renvoie les possibilités de chiffres dans une case
Definition: code.c:181
int dy[]
Definition: code.c:37
void afficher_cages(int **cage_identifiant, int h, int w)
affiche la grille des cages
Definition: code.c:526
void afficher_indices_par_cages(int ***tab, int nombre_cages, int *cage_sizes)
affiche tous les indices des cases d'une même cage
Definition: code.c:505
int main()
Definition: code.c:537
int cpt
Definition: code.c:19
type choix
Definition: code.c:29
int indice[2]
Definition: code.c:30
int nombre
Definition: code.c:32
int tab[6]
Definition: code.c:31
type compteur de boucle