/* ESI CS 2506. Correction de la feuille 2 Pour compiler ce fichier, il faut faire appel a la librairie mathematique avec l'option -lm Credit : certains des programmes presentes ont ete realises par Pierre Cohort */ #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <math.h> /* pour les fonctions sqrt, floor, ... */ /* exercice I */ double conversion(int somme_en_francs) /* Conversion des francs en euros ENTREE : somme en francs SORTIE : equivalent en euros */ { const double taux=6.55957; return (double)somme_en_francs/taux; /* commentaire : la syntaxe (double) devant le parametre somme_en_francs signifie que celui-ci est, dans la division, converti en double. La conversion est en fait ici automatique (un entier divise ou multiplie par un reel est toujours converti en reel). */ } void table_franc_euro(int smin, int smax, int pas) /* Affichage de la table de conversion francs -> euros ENTREE : smin somme minimale smax somme maximale pas increment SORTIE : A l'ecran, affichage de la table */ { int i; for (i=smin; i<=smax; i+=pas){ printf("%d francs = %f euros\n",i,conversion(i)); } } int main_exercice1() { table_franc_euro(0, 100, 5); return 0; } /* exercice II */ int main_exercice2() { int i,j; for (i=0;i<=10;i++){ for (j=0;j<=10;j++){ printf("%4d",i*j); } printf("\n"); } return 0; } /* exercice III */ /* Attention a la difficulte suivante : Si on calcule n! pour n=16, on depasse la capacite de int */ int Hermite(int n) /* Calcul du n-ieme nombre de Hermite ENTREE : n SORTIE : Hn */ { int i, res; if (n%2!=0) res=0; else { /* (-1)^(n/2) */ if (n%4==0) res=1; else res=-1; /* n!/[(n/2)!] */ for (i=n/2+1;i<=n;i++) res*=i; } return res; } int main_exercice3() { int i; /* Les 17 premiers termes sont H0,...,H16 */ for (i=0;i<=16;i++) printf("H%d=\t%d\n",i,Hermite(i)); return 0; } /* exercice IV */ int Fibonacci(int n) /* n-ieme terme de la suite de Fibonacci ENTREE : n SORTIE : Un ou U est la suite de Fibonacci */ { int u0=0, u1=1, u2, i; for (i=2;i<=n;i++){ u2=u0+u1; u0=u1; u1=u2; } return u2; } /* commentaire : si on desire calculer a differents moments plusieurs valeurs de la suite, la fonction precedente n'est pas efficace car elle induit le recalcul des premiers termes de la suite pour chaque nouvelle valeur demandee. On peut resoudre ce probleme en conservant en memoire le dernier indice calcule et la valeur correspondante de u. */ int Fibonacci_Static(int n) /* n-ieme terme de la suite de Fibonacci ENTREE : n SORTIE : Un ou U est la suite de Fibonacci Fonction utilisant des variables statiques, plus efficasses en cas d'appels pour des termes successifs */ { int i; static int u0=0,u1=1,u2,_n=2; /* en presence du mot cle static, les initialisations precedentes sont effectuees une seule fois (au premier appel de la fonction). Les valeurs de u0,u1,u2 et i sont ensuite conservees en memoire entre les differents appels a la fonction. */ for (i=_n;i<=n;i++){ u2=u0+u1; u0=u1; u1=u2; } _n=n+1; /* la variable _n contient l'indice de depart des calculs au prochain appel. Noter que les appels successifs a Fibonacci doivent etres faits avec une suite croissante d'entiers. */ return u2; } int main_exercice4() { printf("fibonacci(12) = %d\n",Fibonacci(12)); printf("fibonacci(12) = %d\n",Fibonacci_Static(12)); return 0; } /* Exercice V */ void PiecesARendre(int MontantARendre, int TypeDePiece) /* Affiche le nombre de pieces (de type TypeDePiece) a rendre pour le montant MontantARendre ENTREE : MontantARendre est le montant a rendre en centimes d'euros TypeDePiece est la valeur de la piece en centimes d'euros SORTIE : Aucune mais le programme affiche les messages a l'ecran */ { int ARendre; ARendre=MontantARendre/TypeDePiece; printf("Rendre %d piece(s) de %.2f euro(s)\n",ARendre,(float)TypeDePiece/100); } int ResteARendre(int MontantARendre, int TypeDePiece) /* Indique ce qui reste a rendre une fois que les pieces TypeDePiece ont ete rendues. ENTREE : MontantARendre est le montant a rendre en centimes d'euros TypeDePiece est la valeur de la piece en centimes d'euros SORTIE : Montant restant a rendre */ { return (MontantARendre%TypeDePiece); } void RenduMonnaie (int PrixArticle, int MontantPaye) /* Affiche le nombre de pieces a rendre afin de minimiser le nombre de pieces rendues. ENTREE : PrixArticle est le prix de l'article achete MontantPaye est le montant paye par l'acheteur SORTIE : Aucune mais le programme affiche les messages a l'ecran */ { int MontantARendre, Reste; MontantARendre=MontantPaye-PrixArticle; assert(MontantARendre>=0); PiecesARendre(MontantARendre,200); Reste=ResteARendre(MontantARendre,200); PiecesARendre(Reste,100); Reste=ResteARendre(MontantARendre,100); PiecesARendre(Reste,50); Reste=ResteARendre(MontantARendre,50); PiecesARendre(Reste,20); Reste=ResteARendre(MontantARendre,20); PiecesARendre(Reste,10); assert(ResteARendre(MontantARendre,10)==0); } void main_exercice5() /* On verifie sur l'exemple */ { RenduMonnaie(430,570); } /* exercice VI */ /* Question 1 */ /* Notons Qi le quotient de la division entiere de Ni par 97. On a N1=97Q1+R1 et N2=97Q2+R2. D'autre part N0=10^6N1+N2 ainsi N0=10^6(97Q1+R1)+(97Q2+R2)=97*(10^6Q1+Q2)+10^6R1+R2 Or 10309*97=999973 donc 10^6=10309*97+27, par suite N0=97*(10^6Q1+Q2+10309)+27R1+R2 ainsi R0=N0 mod 97=97*(10^6Q1+Q2+10309)+27R1+R2 mod 97 donc R0=27R1+R2 mod 97 */ /* Question 2 */ int clef (long int N1, long int N2) /* Calcul de la clef d'un numero de securite sociale ENTREE : N1 les 7 premiers chiffres du numero SS N2 les 6 derniers chiffres du numero SS SORTIE : clef du numero SS Cette fonction utilise la formule etablie dans la question 1 */ { int R0, R1, R2; R1=N1%97; R2=N2%97; R0=(27*R1+R2)%97; return(97-R0); } /* Question 3 */ void main_exercice6() { int groupe1, groupe2, groupe3, groupe4, groupe5, groupe6; long int N1, N2; printf("Entrez le numero de securite sociale en separant les 6 groupes par un espace.\n"); scanf("%d %d %d %d %d %d",&groupe1,&groupe2,&groupe3,&groupe4,&groupe5,&groupe6); /* N1 comprend les 7 premiers chiffres et N2 les 6 deriniers */ N1=groupe4+100*groupe3+10000*groupe2+1000000*groupe1; N2=groupe6+groupe5*1000; /* Affichage de la clef */ printf("La clef associee a ce numero est %d\n",clef(N1,N2)); /* Affichage homme/femme */ if ((groupe1==1)||(groupe1==7)) printf("L'individu est un homme\n"); else printf("L'individu est une femme\n"); /* Affichage du lieu de naissance */ if ((groupe4==99)||((groupe2<=64)&&(groupe4>=90)&&(groupe4<=96))) /* Dans la gestion du groupe4 entre 90 et 96, on ne gere pas le cas des individus nes apres l'an 2000 */ printf("L'individu est ne a l'etranger\n"); else printf("L'individu est ne en France\n"); } /* main */ int main() { int n; printf("Feuille d'exercices 2\n"); printf("Choix de l'exercice : "); scanf("%d",&n); switch (n) { case 1: main_exercice1(); break; case 2: main_exercice2(); break; case 3: main_exercice3(); break; case 4: main_exercice4(); break; case 5: main_exercice5(); break; case 6: main_exercice6(); break; } return 0; }