examen-S720006-janvier-2006_3

7
Licence MIAGe Universit´ e de Nantes S720006 2005/2006 Examen Langage C Dur ´ ee : 1h30 Le bar` eme est donn´ e` a titre indicatif uniquement. Les copies de transparents du cours, le polycopi´ e de L. Granvilliers et les notes manuscrites personnelles sont les seuls documents autoris ´ es. Exercice 1 (6 pts.) Le sudoku est un puzzle utilisant une grille carr´ ee compos´ ee de 9 r´ egions ; chaque r´ egion est elle-mˆ eme compos´ ee de 9 cases. On part d’une grille partiellement remplie et on doit la compl´ eter en respectant les trois r` egles suivantes : – Chaque colonne doit contenir les 9 chiffres de 1 ` a 9 – Chaque ligne doit contenir les 9 chiffres de 1 ` a 9 – Chaque r´ egion doit contenir les 9 chiffres de 1 ` a 9 3 2 5 4 7 1 8 0 6 2 3 7 8 7 9 1 3 6 8 9 1 5 7 8 2 6 7 8 9 2 3 4 6 1 2 4 6 7 9 1 3 4 6 7 9 2 4 6 8 9 1 5 4 9 6 4 3 6 2 5 3 8 5 7 3 5 2 8 1 7 1 4 3 5 1 8 9 5 5 4 7 2 6 1 2 3 4 5 8 1 5 4 9 6 4 5 8 3 2 1 6 7 2 5 4 3 9 6 2 4 8 3 5 8 2 5 1 5 3 4 9 8 7 5 1 1 5 7 3 Région 1. D´ efinir un type structur´ e digits t pour repr´ esenter un tableau de 9 entiers susceptible de contenir une ligne, une colonne, ou une r´ egion ; 2. ´ Ecrire la fonction contient les 9 chiffres() prenant en entr´ ee un digits t et retournant 1 si le tableau correspondant contient tous les chiffres de 1 ` a 9 une seule fois ; 3. ´ Ecrire les fonctions extraire ligne(), extraire colonne() et extraire region() prenant en entr´ ee une grille de sudoku sous la forme d’un tableau d’entiers ` a 2 dimensions et un entier n compris entre 0 et 8, et retournant la n-i` eme ligne, la n-i` eme colonne, ou la n-i` eme r´ egion ; 4. ´ Ecrire la fonction sudoku fini() prenant en entr´ ee une grille de sudoku et retournant 1 si elle est cor- rectement compl´ et´ ee. Exercice 2 (5 pts.) 1. Indiquez les erreurs se trouvant dans le programme ci-dessous et corrigez-les : 1. #include "stdlib.h" 2. 3. typedef struct { 4. cellule suiv; 5. int val; 6. } cellule; 7. 8. void creer_cellule(cellule * c, int v) { 9. c=(cellule * )malloc(sizeof(cellule * )); 10. } 11. 12. int main(void) { 13. cellule * c; 14. creer_cellule(c,45); 15. return 1; 16. } S720006 — Universit´ e de Nantes Examen — Langage C Dur´ ee : 1h30 1/2

description

exam en luanguage c de fst tanger

Transcript of examen-S720006-janvier-2006_3

Page 1: examen-S720006-janvier-2006_3

Licence MIAGe Universite de NantesS720006 2005/2006

ExamenLangage C

Duree : 1h30

Le bareme est donne a titre indicatif uniquement.

Les copies de transparents du cours, le polycopie de L. Granvilliers et les notes manuscritespersonnelles sont les seuls documents autorises.

Exercice 1 (6 pts.)

Le sudoku est unpuzzleutilisant une grille carree composee de 9 regions ; chaque region est elle-meme composeede 9 cases. On part d’une grille partiellement remplie et on doit la completer en respectant les trois regles suivantes :– Chaque colonne doit contenir les 9 chiffres de1 a9

– Chaque ligne doit contenir les 9 chiffres de1 a9

– Chaque region doit contenir les 9 chiffres de1 a9

3

2

54

7

1

8

0

6

2 3

7

8 79 1

3

6

8

9

1

5

7 8 26

7

89

2

3

4

6

1

2 4

67

9 1

3

46

7 9

2

4

68

9

1

5

4 9

6

4

3

6 2

5

38 5 7

3528

1

7 14

35

1

8

9 5

5

4

7

2

612

3

4 5 8 1

5

4 9

6

4 5 8

3

2 1 6

7

2

5

4

3

9

6 2

4

8 3

5

8 2 5

1

5 3

4

9

8

7

5

1

1

5 7

3

Région

1. Definir un type structure digits t pour representer un tableau de 9 entiers susceptible de contenir uneligne, une colonne, ou une region ;

2. Ecrire la fonctioncontient les 9 chiffres() prenant en entree undigits t et retournant1 si letableau correspondant contient tous les chiffres de1 a9 une seule fois ;

3. Ecrire les fonctionsextraire ligne() , extraire colonne() et extraire region() prenanten entree une grille de sudoku sous la forme d’un tableau d’entiersa 2 dimensions et un entiern comprisentre0 et8, et retournant lan-ieme ligne, lan-ieme colonne, ou lan-ieme region ;

4. Ecrire la fonctionsudoku fini() prenant en entree une grille de sudoku et retournant1 si elle est cor-rectement completee.

Exercice 2 (5 pts.)

1. Indiquez les erreurs se trouvant dans le programme ci-dessous et corrigez-les :

1. #include "stdlib.h"2.3. typedef struct {4. cellule suiv;5. int val;6. } cellule;7.

8. void creer_cellule(cellule * c, int v) {9. c=(cellule * )malloc(sizeof(cellule * ));

10. }11.12. int main(void) {13. cellule * c;14. creer_cellule(c,45);15. return 1;16. }

S720006 — Universite de Nantes Examen — Langage C

Duree : 1h301/2

Page 2: examen-S720006-janvier-2006_3

2. Une chaınecorrectement parentheseecontient le meme nombre de parentheses ouvrantes et fermantes. Deplus, en tout point de la chaıne, on ne doit jamais avoir vu plus de parentheses fermantes que de parenthesesouvrantes.Ecrire la fonctionincorrectement parenthesee() prenant une chaıne de caracteres en entree etretournant suivant les cas :– l’oppose de la position (a partir de1) de la premiere parenthese fermante en trop, s’il y a lieu ;– le nombre de parentheses ouvrantes en trop (ou 0 si la chaıne est correctement parenthesee).Exemples :

Appel Resultatincorrectement parenthesee("(sdf(gfdgj)dslfkj)") 0incorrectement parenthesee("(sdf(gfdgjdslfkj)") 1incorrectement parenthesee("(sdf(gfdgjdslfkj()") 2incorrectement parenthesee("(sdf(gfd)))gjdslfkj()") -11

Exercice 3 (9 pts.)

On souhaite developper une librairie de manipulation de nombres entierspositifs de grande taille. Pour cela, onrepresentera un nombre entier par un tableau d’entiers dont chaque case correspondraa un chiffre. Par commodite,les chiffres d’un nombre seront stockes de la droite vers la gauche dans le tableau :

2345965780 1 2 3 4 5 6 7 8

8 7 5 6 9 5 4 3 2

1. Definir le typeentier representant un entier dont le nombre de chiffres n’est connu qu’a l’execution duprogramme ;

2. Ecrire la fonctioncreer entier() qui prend en entree un pointeur sur un tableau de chiffrestab et unetaille sz , et qui retourne unentier representant l’entier contenu danstab . La fonction devra retournerl’ entier codant0 si tab pointe surNULL;

3. Ecrire la fonctiondetruire entier() liberant la memoire occupee par un entier ;

4. Ecrire la fonctionchaine en entier() prenant en entree une chaıne de caracteres representant un grandentier positif et retournant l’entier correspondant. On ne gerera pas le cas ou la chaıne ne represente pasun entier positif ;

5. Ecrire la fonctionentier en chaine() prenant en entree unentier et retournant la chaıne de ca-racteres allouee dynamiquement qui lui correspond ;

6. Ecrire la fonctionajouter entiers() prenant en entree deuxentier se1 ete2 et retournant l’entiercorrespondanta leur somme. Les entierse1 ete2 peuventetre de tailles differentes :

4 6 8 4

5

37 5

36+

1

9 2

1

3 5 8 3 6 5 8 2 4

428563497 + 356 = 428563853

7. Ecrire la fonctionmain() pour un programme prenant en parametres sur la ligne de commande deux entierspositifs de taille arbitraire et affichant leur sommea l’ecran. Le programme devra s’arreter en affichant unmessage sur le canal d’erreur standard si le nombre de parametres est mauvais.

S720006 — Universite de Nantes Examen — Langage C

Duree : 1h302/2

Page 3: examen-S720006-janvier-2006_3

Licence MIAGe Universite de NantesS720006 2005/2006

ExamenLangage C

Duree : 1h30

— CORRECTION —

Corrig e exercice 1 (6 pts.)

#include <stdio.h>

typedef int sudoku_t[9][9];

// On d eclare une structure pour pouvoir la rendre en r esultat d’une fonctiontypedef struct {

int T[9];} digits_t;

int contient_les_9_chiffres(digits_t l){

int occurrences[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};for (int i = 0; i < 9; ++i) {

if (occurrences[l.T[i]-1]++ != 0) { // Chiffre l[i] d ej a vu ?return 0;

}}return 1;

}

digits_t extraire_ligne(sudoku_t sdk, int i){

digits_t l;for (int j = 0; j < 9; ++j) {

l.T[j] = sdk[i][j];}return l;

}

digits_t extraire_colonne(sudoku_t sdk, int j){

digits_t c;for (int i = 0; i < 9; ++i) {

c.T[i] = sdk[i][j];}return c;

}

digits_t extraire_region(sudoku_t sdk, int n){

digits_t r;int idx = 0;

for (int i = 3 * (n/3); i < 3 * (n/3) + 3; ++i) {for (int j = 3 * (n%3); j < 3 * (n%3)+3; ++j) {

r.T[idx++] = sdk[i][j];}

}return r;

S720006 — Universite de Nantes Examen — Langage C

Duree : 1h301/5

Page 4: examen-S720006-janvier-2006_3

}

int sudoku_fini(sudoku_t sdk){

// V erification sur les lignesfor (int i = 0; i < 9; ++i) {

if (!contient_les_9_chiffres(extraire_ligne(sdk,i))) {return 0;

}}// V erification sur les colonnesfor (int j = 0; j < 9; ++j) {

if (!contient_les_9_chiffres(extraire_colonne(sdk,j) )) {return 0;

}}// V erification sur les r egionsfor (int n = 0; n < 9; ++n) {

if (!contient_les_9_chiffres(extraire_region(sdk,n)) ) {return 0;

}}return 1;

}

int main(void){

int sdk[9][9] = {{1, 2, 3, 4, 5, 8, 6, 7, 9},{5, 8, 6, 3, 9, 7, 2, 1, 4},{4, 9, 7, 2, 1, 6, 3, 5, 8},{3, 7, 8, 1, 6, 2, 9, 4, 5},{9, 1, 4, 5, 7, 3, 8, 6, 2},{6, 5, 2, 9, 8, 4, 7, 3, 1},{2, 4, 5, 7, 3, 9, 1, 8, 6},{7, 6, 1, 8, 2, 5, 4, 9, 3},{8, 3, 9, 6, 4, 1, 5, 2, 7}

};

printf("=> %d\n", sudoku_fini(sdk));return 0;

}

Corrig e exercice 2 (5 pts.)

1. Erreurs :

Ligne 1. Remplacer les guillemets par des chevrons autour de stdlib.h

Ligne 4. Le type cellule n’existe pas encore. Utiliser un pointeur

Lignes 8 et 13–14.Il faut passer un pointeur sur un pointeur de cellule pour changer la valeurde c avec malloc()

Ligne 9. Il faut utiliser sizeof(cellule)

Ligne 15. Retourner 0

2. Solution :

#include <stdio.h>

int incorrectement_parenthesee(char str[]){

int openpar = 0;int idx = 0;while (str[idx] != ’\0’ && openpar >= 0) {

switch (str[idx]) {case ’(’:

++openpar;

S720006 — Universite de Nantes Examen — Langage C

Duree : 1h302/5

Page 5: examen-S720006-janvier-2006_3

break;case ’)’:

--openpar;break;

}++idx;

}if (openpar < 0) { // Trop de parenth eses fermantes

return -idx; // => on retourne l’oppos e de la position entre 1 et n de la// 1 ere parenth ese en trop

}// On retourne le nombre de parenth eses ouvrantes en tropreturn openpar;

}

int main(void){

char * str;

str = "(sdf(gfdgj)dslfkj)";printf("\\code{incorrectement\\_parenthesee(\"%s\") } & %d\\\\\n",

str,incorrectement_parenthesee(str));str = "(sdf(gfdgjdslfkj)";printf("\\code{incorrectement\\_parenthesee(\"%s\") } & %d\\\\\n",

str,incorrectement_parenthesee(str));str = "(sdf(gfdgjdslfkj()";printf("\\code{incorrectement\\_parenthesee(\"%s\") } & %d\\\\\n",

str,incorrectement_parenthesee(str));str = "(sdf(gfd)))gjdslfkj()";printf("\\code{incorrectement\\_parenthesee(\"%s\") } & %d\\\\\n",

str,incorrectement_parenthesee(str));return 0;

}

Corrig e exercice 3 (9 pts.)

// Repr esentation d’entiers de taille arbitraire#include <stdio.h>#include <string.h>#include <stdlib.h>

char charlookup[] = {’0’, ’1’,’2’,’3’,’4’,’5’,’6’,’7’,’ 8’,’9’};

typedef struct {unsigned int * nb; // Repr esentation de l’entier par un tableau

// L’entier est cod e avec le chiffre de poids faible// en premier

unsigned int sz; // Nombre de chiffres de l’entier} entier;

unsigned int min(unsigned int x, unsigned int y){

return (x <= y) ? x : y;}

unsigned int max(unsigned int x, unsigned int y){

return (x >= y) ? x : y;}

entier chaine_en_entier(char ec[]){

unsigned int sz = strlen(ec);entier e;e.nb = (unsigned int * )malloc(sizeof(unsigned int) * sz);e.sz = sz;for (unsigned int i = 0; i < sz; ++i) {

e.nb[i] = ec[sz-i-1]-’0’;

S720006 — Universite de Nantes Examen — Langage C

Duree : 1h303/5

Page 6: examen-S720006-janvier-2006_3

}return e;

}

entier creer_entier(unsigned int sz, unsigned int * tab){

entier e;e.nb = (unsigned int * )malloc(sizeof(unsigned int) * sz);e.sz = sz;if (tab != (unsigned int * )NULL) {

for (unsigned int i = 0; i < sz; ++i) {e.nb[i] = tab[i];

}} else {

for (unsigned int i = 0; i < sz; ++i) {e.nb[i] = 0;

}}return e;

}

void detruire_entier(entier e){

free(e.nb);}

char * entier_en_chaine(entier e){

char * ch = (char * )malloc(sizeof(char) * e.sz + 1);for (unsigned int i = 0; i < e.sz; ++i) {

ch[i] = charlookup[e.nb[e.sz-i-1]];}ch[e.sz] = ’\0’;

return ch;}

void additionneur(unsigned int a, unsigned int b, unsigned int carryin,unsigned int * c, unsigned int * carryout)

{unsigned int s = a+b+carryin;

if (s > 9) {

* carryout = 1;

* c = s - 10;} else {

* carryout = 0;

* c = s;}

}

entier ajouter_entiers(entier a, entier b){

entier c= creer_entier(max(a.sz,b.sz)+1,(unsigned int * )NULL);unsigned int minsz = min(a.sz,b.sz);

// Sommation des chiffres de la droite vers la gauche// pour tous les chiffres non nulsadditionneur(a.nb[0],b.nb[0],0,&c.nb[0],&c.nb[1]);for (unsigned int i = 1; i < minsz; ++i) {

additionneur(a.nb[i],b.nb[i],c.nb[i],&c.nb[i],&c.nb [i+1]);}

if (a.sz != b.sz) {// Ajout des chiffres surnum eraires du nombre le plus grandif (a.sz == minsz) { // Ajout des chiffres de b

c.nb[minsz] += b.nb[minsz];for (unsigned int i = minsz+1; i < b.sz; ++i) {

c.nb[i] = b.nb[i];}

} else { // Ajout des chiffres de a

S720006 — Universite de Nantes Examen — Langage C

Duree : 1h304/5

Page 7: examen-S720006-janvier-2006_3

c.nb[minsz] += a.nb[minsz];for (unsigned int i = minsz+1; i < a.sz; ++i) {

c.nb[i] = a.nb[i];}

}}// On regarde si le chiffre suppl ementaire a et e utilis eif (c.nb[c.sz-1] == 0) {

--c.sz;// On ne cherche pas a r eallouer la m emoire suppl ementaire

}

return c;}

int main(int argc, char * argv[]){

if (argc != 3) {fprintf(stderr,"Erreur: addition <nb1> <nb2>\n");return 1;

}

entier e1 = chaine_en_entier(argv[1]);entier e2 = chaine_en_entier(argv[2]);

char * ch = entier_en_chaine(ajouter_entiers(e1,e2));

printf("%s\n",ch);

free(ch);detruire_entier(e1);detruire_entier(e2);

return 0;}

S720006 — Universite de Nantes Examen — Langage C

Duree : 1h305/5