/*
CS 203. 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*N1+N2)%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;
}