/* Solution proposee par Ning Hu, legerement modifiee */
#include <stdio.h>
#include "polynome.h"
//comment in the following line when building the polynome library
//it will remove main in compilation or at compile tile use -D IS_LIBRARY
//-----------------------------------------------------------------
//#define IS_LIBRARY
//----------------
#ifndef IS_LIBRARY
//---------------
//------------------
//main driver method
//------------------
main()
{
node *head,*p,*q;
poly *p1,*p2,*p3;
int choix,i;
float constant;
//initialization
head = NULL;
while(1)
{
//demander le choix
printf("***************************************\n");
printf("Qu'est que vous voulez?\n");
printf("1) cree un polynome\n");
printf("2) mettre les polynomes a l'ecran\n");
printf("3) recalculer tous les polynomes\n");
printf("4) ajouter deux polynomes ensemble\n");
printf("5) multiplier un polynome par une constante\n");
printf("6) multiplier deux polynomes ensemble\n");
printf("7) evaluer le polynome\n");
printf("0) quitter\n");
printf("***************************************\n");
//performer le action
scanf("%i",&choix);
switch(choix)
{
case 0://detruire touts les polynomes et quitter
for(p = head,q = head;
p != NULL;
q = p, p = p->next, free(q) );
exit(0);
case 1://cree un polynome
head = ajouter_a_list(head,cree());
break;
case 2://mettre les polynomes a l'ecran
printf("les polynomes:\n");
montre_plusiers(head);
break;
case 3: //calculer tous les polynomes
for(p = head; p != NULL; p = p->next )
p->poly = calculer(p->poly);
break;
case 4: //ajouter deux polynomes ensemble
//mettre touts les polynomes a le ecran
montre_plusiers(head);
p1 = choisir_poly(head);
p2 = choisir_poly(head);
p3 = ajouter(p1,p2); //ajouter
//montre le resultat
printf("La result: ");
montre(p3);
//ajouter le resultat a la liste
head = ajouter_a_list(head,p3);
break;
case 5: //multiplier un polynome par une constante
//mettre tous les polynomes a l'ecran
montre_plusiers(head);
p1 = choisir_poly(head);
printf("donner un const svp:");
scanf("%f",&constant);
//faire la multiplication avec une autre function
multiplier_const(p1,constant);
//montre le result
printf("La result: ");
montre(p1);
break;
case 6: //multiplier deux polynomes ensemble
//mettre touts les polynomes a l'ecran
montre_plusiers(head);
p1 = choisir_poly(head);
p2 = choisir_poly(head);
p3 = multiplier(p1,p2); //multiplier
//montre le result
printf("La result: ");
montre(p3);
//ajouter le result a la liste
head = ajouter_a_list(head,p3);
break;
case 7: //evaluer le polynome
montre_plusiers(head);
p1 = choisir_poly(head);
printf("donner un const a evaluer svp:");
scanf("%f",&constant);
constant = (float)evaluer_a_horner(p1,constant);
//montrer le resultat
printf("La result est: %f\n",constant);
}
}
}
//----
#endif
//----
//---------------------------------------------------
//desc = this method chooses a polynome from a list
//input = link list (node pointer)
//output = poly struct
//---------------------------------------------------
poly* choisir_poly(node *head)
{
int choix,i;
node *p;
poly *p1;
printf("choisir un polynome svp:");
scanf("%i",&choix);
//chercher le polynome
for(p = head,i = 0;
p != NULL, i < choix;
p = p->next, i++ )
{
p1 = p->poly;
}
if(i != choix)
{
printf("mauvais choix\n");
return 0;
}
else return p1;
}
//---------------------------------------------------
//desc = this method adds a polynome to a list
//input = link list (node struct pointer) and polynomial
//output = link list (node struct pointer)
//---------------------------------------------------
node* ajouter_a_list(node* head, poly* p1)
{
node *p,*q;
//ajouter le resultat a la liste
p = (node*)malloc(sizeof(node));
if(head == NULL)
{
head = p;
head->next = NULL;
head->poly = p1;
}
else //must add at end of list
{
p->next = NULL;
p->poly = p1;
q = head;
while(q->next != NULL)
q = q->next;
q->next = p;
}
return head;
}
//---------------------------------------------------
//desc = this method prints a list of polys to screen
//input = link list(node struct pointer)
//output = null
//---------------------------------------------------
void montre_plusiers(node* head)
{
node *p;
int i;
//mettre tous les polynomes a l'ecran
for(p = head, i = 1;
p != NULL;
p = p->next,i++ )
{
printf("%i) ",i);
montre(p->poly);
}
}
//---------------------------------------------------
//desc = this method creates a poly nomial structure
//input = null
//output = poly struct
//---------------------------------------------------
poly* cree(void)
{
poly* nouveau;
int i;
float coeff;
nouveau = (poly*)malloc(sizeof(poly));
printf("la degree est:");
scanf("%i",&(nouveau->degree));
nouveau->coefficient = (float*)malloc(sizeof(float)*(nouveau->degree+1));
for(i = nouveau->degree; i >= 0; i--)
{
printf("entre le coefficient de la degree %i:-->",i);
scanf("%f",&coeff);
nouveau->coefficient[i] = coeff;
}
return nouveau;
}
//-----------------------------------------------------
//desc = this method prints a polynomial to the screen
//input = pointer to a poly struct
//output = null
//-----------------------------------------------------
void montre(poly* p)
{
int i;
printf("--> ");
for(i = p->degree; i > 0; i--)
{
if(p->coefficient[i] != 0)
printf("%.2f(X^%i) + ",p->coefficient[i],i);
}
printf("%.2f\n",p->coefficient[0]);
}
//-----------------------------------------------------
//desc = this method recalculates the degree of a polynomial
//input = pointer to a poly struct
//output = pointer to a new poly struct if changes are made
//-----------------------------------------------------
poly* calculer(poly* p)
{
int i,save;
poly* q;
save = p->degree;
for(i = p->degree; i > 0; i--)
{
if(p->coefficient[i] == 0) //highest degree coeff = 0, decrement degree
(p->degree)--;
}
//recreate poly if degree has changed
if(save == p->degree)
return p;
q = (poly*)malloc(sizeof(poly));
q->degree = p->degree;
q->coefficient = (float*)malloc(sizeof(float)*(q->degree+1));
for(i = p->degree ; i >= 0; i--)
q->coefficient[i] = p->coefficient[i];
printf("Ce polynome a change de degree de %i a %i\n",save,p->degree);
montre(p);
free(p);
return q;
}
//-----------------------------------------------------
//desc = this method adds two polynomials together
//input = two pointers to poly structs
//output = pointer to a new poly struct
//-----------------------------------------------------
poly* ajouter(poly* p1,poly* p2)
{
poly *nouveau;
int i;
//error check
if( (p1 == NULL) || (p2 == NULL))
{
perror("Null pointer encountered in ajouter\n");
return NULL;
}
nouveau = (poly*)malloc(sizeof(poly));
//degree est la max des deux polys
if(p1->degree > p2->degree)
nouveau->degree = p1->degree;
else
nouveau->degree = p2->degree;
nouveau->coefficient = (float*)malloc(sizeof(float)*(nouveau->degree+1));
//initialier a zero
for(i = nouveau->degree; i >= 0; i--)
nouveau->coefficient[i] = 0;
//add p1 to nouveau
for(i = p1->degree; i >= 0; i--)
nouveau->coefficient[i] += p1->coefficient[i];
//add p2 to nouveau
for(i = p2->degree; i >= 0; i--)
nouveau->coefficient[i] += p2->coefficient[i];
return nouveau;
}
//-----------------------------------------------------
//desc = this method multiplies two polynomials together
//input = pointers to two poly structs
//output = pointer to a new poly struct
//-----------------------------------------------------
poly* multiplier(poly* p1,poly* p2)
{
poly *nouveau;
int i,j,degree;
double result;
//error check
if( (p1 == NULL) || (p2 == NULL))
{
perror("Null pointer encountered in multiply of two polys\n");
return NULL;
}
nouveau = (poly*)malloc(sizeof(poly));
//degree est la sum des deux polys
nouveau->degree = p1->degree + p2->degree;
nouveau->coefficient = (float*)malloc(sizeof(float)*(nouveau->degree+1));
//initialier a zero
for(i = nouveau->degree; i >= 0; i--)
{
nouveau->coefficient[i] = 0;
}
for(i = 0; i <= p1->degree; i++)//loop through 1st polynome
{
for(j = 0; j <= p2->degree; j++ )//loop through 2nd polynome
{
degree = i + j; //new degree for coefficient
//calculate coefficient
result = (p1->coefficient[i] * p2->coefficient[j]);
nouveau->coefficient[degree] += result;
}
}
return nouveau;
}
//-----------------------------------------------------
//desc = this method multiplies a polynomial by a const
//input = a pointer to a poly struct and a const double
//output = pointer to the same poly struct
//-----------------------------------------------------
poly* multiplier_const(poly *p,double n)
{
int i;
for(i = p->degree; i >= 0; i--)
p->coefficient[i] *= n;
return p;
}
//-----------------------------------------------------
//desc = this method evaluates a polynome using horner's rule
//input = a pointer to a poly struct and a const double
//output = double value
//-----------------------------------------------------
double evaluer_a_horner(poly *p,double n)
{
//variables
double sum;
int i;
//action
sum = (p->coefficient[p->degree]);
for(i = p->degree; i > 0 ;i--)
{
sum = (sum * n) + p->coefficient[i-1];
}
return sum;
}
//-----------------------------------------------------
//desc = this method makes a copy of a polynomial
//input = a pointer to a poly struct
//output = a pointer to a new poly struct. the original is unaffected
//-----------------------------------------------------
poly* copy(poly* ptr_oldPoly)
{
poly *ptr_newPoly;
int i;
ptr_newPoly = (poly*)malloc(sizeof(poly));
ptr_newPoly->coefficient=(float*)malloc(sizeof(float)*(ptr_oldPoly->degree+1));
ptr_newPoly->degree = ptr_oldPoly->degree;
for(i = 0; i <= ptr_oldPoly->degree; i++)
ptr_newPoly->coefficient[i] = ptr_oldPoly->coefficient[i];
return ptr_newPoly;
}
//-----------------------------------------------------
//desc = this method destroys a polynomial object
//input = a pointer to a poly struct
//output = nothing.
//-----------------------------------------------------
void destroy(poly *p)
{
//just in case
if(p == NULL)
return;
free(p->coefficient);
free(p);
}