From 49e8f4a7d700c8f525dd5064d03d2b41abe3dc48 Mon Sep 17 00:00:00 2001 From: Ankita19ms0010 <69465093+Ankita19ms0010@users.noreply.github.com> Date: Fri, 18 Sep 2020 22:53:49 +0530 Subject: [PATCH] feat:Add Polynomial Addition (#600) * feat:Add Polynomial Addition * Review changes * updating DIRECTORY.md * Apply suggestions from code review Co-authored-by: David Leal * Corrected printing Co-authored-by: David Leal * file path fixed * updating DIRECTORY.md * Corrected free memory Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal --- DIRECTORY.md | 1 + misc/poly_add.c | 319 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 320 insertions(+) create mode 100644 misc/poly_add.c diff --git a/DIRECTORY.md b/DIRECTORY.md index 16cf56c1..f54d8fac 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -248,6 +248,7 @@ * [Mirror](https://github.com/TheAlgorithms/C/blob/master/misc/mirror.c) * [Palindrome](https://github.com/TheAlgorithms/C/blob/master/misc/palindrome.c) * [Pid](https://github.com/TheAlgorithms/C/blob/master/misc/pid.c) + * [Poly Add](https://github.com/TheAlgorithms/C/blob/master/misc/poly_add.c) * [Prime](https://github.com/TheAlgorithms/C/blob/master/misc/prime.c) * [Prime Factoriziation](https://github.com/TheAlgorithms/C/blob/master/misc/prime_factoriziation.c) * [Quartile](https://github.com/TheAlgorithms/C/blob/master/misc/quartile.c) diff --git a/misc/poly_add.c b/misc/poly_add.c new file mode 100644 index 00000000..53e76c39 --- /dev/null +++ b/misc/poly_add.c @@ -0,0 +1,319 @@ +/** + * @file + * @brief Implementation of [Addition of two polynomials] + * (https://en.wikipedia.org/wiki/Polynomial#Addition) + * @author [Ankita Roy Chowdhury](https://github.com/Ankita19ms0010) + * @details + * This code takes two polynomials as input + * and prints their sum using linked list. + * The polynomials must be in increasing or decreasing order of degree. + * Degree must be positive. + */ +#include // for io operations +#include + +/** + * @brief identifier for single-variable polynomial coefficients as a linked + * list + */ +struct term +{ + int coef; /**< coefficient value */ + int pow; /**< power of the polynomial term */ + struct term *next; /**< pointer to the successive term */ +}; + +/** + * @brief Frees memory space + * @param poly first term of polynomial + * @returns void + */ +void free_poly(struct term *poly) +{ + if (!poly) + { + return; // NULL pointer does not need delete + } + else + { + while (!poly->next) + { + free(poly->next); // Deletes next term + } + free(poly); // delete the current term + } +} + +/** + * The function will create a polynomial + * @param poly stores the address of the polynomial being created + * @param coef contains the coefficient of the node + * @param pow contains the degree + * @returns none + */ +void create_polynomial(struct term **poly, int coef, int pow) +{ + // Creating the polynomial using temporary linked lists + struct term *temp1, *temp2; + temp1 = *poly; // Contains the null pointer + + // Initiating first term + if (temp1 == NULL) + { + temp2 = (struct term *)malloc( + sizeof(struct term)); // Dynamic node creation + temp2->coef = coef; + temp2->pow = pow; + // Updating the null pointer with the address of the first node of the + // polynomial just created + *poly = temp2; + temp2->next = NULL; // Increasing the pointer temp2 + } + // Creating the rest of the nodes + else + { + temp2->next = (struct term *)malloc( + sizeof(struct term)); // Dynamic node creation + temp2 = temp2->next; // Increasing the pointer temp2 + temp2->coef = coef; + temp2->pow = pow; + temp2->next = NULL; + } +} + +/** + * The function will add 2 polynomials + * @param poly1 first polynomial of the addition + * @param poly2 second polynomial of the addition + * @param pol the resultant polynomial + */ + +void poly_add(struct term **pol, struct term *poly1, struct term *poly2) +{ + // Creating a temporary linked list to store the resultant polynomial + struct term *temp = (struct term *)malloc(sizeof(struct term)); + temp->next = NULL; + *pol = + temp; //*pol always points to the 1st node of the resultant polynomial + + // Comparing the powers of the nodes of both the polynomials + // until one gets exhausted + while (poly1 && poly2) + { + /* If the power of the first polynomial is greater than the power of the + second one place the power and coefficient of that node of the first + polynomial in temp and increase the pointer poly1 + */ + if (poly1->pow > poly2->pow) + { + temp->coef = poly1->coef; + temp->pow = poly1->pow; + poly1 = poly1->next; + } + /* If the power of the second polynomial is greater than the power of + the first one place the power and coefficient of that node of the + second polynomial in temp and increase the pointer poly2 + */ + else if (poly1->pow < poly2->pow) + { + temp->coef = poly2->coef; + temp->pow = poly2->pow; + poly2 = poly2->next; + } + /* If both of them have same power then sum the coefficients + place both the summed coefficient and the power in temp + increase both the pointers poly1 and poly2 + */ + else + { + temp->coef = poly1->coef + poly2->coef; + temp->pow = poly1->pow; + poly1 = poly1->next; + poly2 = poly2->next; + } + /* If none of the polynomials are exhausted + dynamically create a node in temp + */ + if (poly1 && poly2) + { + temp->next = (struct term *)malloc( + sizeof(struct term)); // Dynamic node creation + temp = temp->next; // Increase the pointer temp + temp->next = NULL; + } + } + /* If one of the polynomials is exhausted + place the rest of the other polynomial as it is in temp + by creating nodes dynamically + */ + while (poly1 || poly2) + { + temp->next = (struct term *)malloc( + sizeof(struct term)); // Dynamic node creation + temp = temp->next; // Increasing the pointer + temp->next = NULL; + + /* If poly1 is not exhausted + place rest of that polynomial in temp + */ + if (poly1) + { + temp->coef = poly1->coef; + temp->pow = poly1->pow; + poly1 = poly1->next; + } + /* If poly2 is not exhausted + place rest of that polynomial in temp + */ + else if (poly2) + { + temp->coef = poly2->coef; + temp->pow = poly2->pow; + poly2 = poly2->next; + } + } +} + +/** + * The function will display the polynomial + * @param poly first term of the polynomial to be displayed + * @returns none + */ +void display_polynomial(struct term *poly) +{ + while (poly != NULL) + { + printf("%d x^%d", poly->coef, poly->pow); + poly = poly->next; + if (poly != NULL) + { + printf(" + "); + } + } +} + +/** + * @brief Test function 1 + * + * @details + * Polynomial 1 is 5 x^2 + 3 x^1 + 2 x^0 + * Polynomial 2 is 7 x^3 + 9 x^1 + 10 x^0 + * Resultant polynomial is 7 x^3 + 5 x^2 + 12 x^1 + 12 x^0 + * @returns void + */ +static void test1(struct term *poly1, struct term *poly2, struct term *poly3) +{ + printf("\n----Test 1----\n"); + printf("\nFirst Polynomial:\n"); // Defining the 1st polynomial + create_polynomial(&poly1, 5, 2); + create_polynomial(&poly1, 3, 1); + create_polynomial(&poly1, 2, 0); + display_polynomial(poly1); + + printf("\nSecond Polynomial:\n"); // Defining the 2nd polynomial + create_polynomial(&poly2, 7, 3); + create_polynomial(&poly2, 9, 1); + create_polynomial(&poly2, 10, 0); + display_polynomial(poly2); + + poly_add(&poly3, poly1, poly2); // Adding the two polynomials + printf("\nResultant polynomial:\n"); + display_polynomial(poly3); + printf("\n"); + + // Frees memory space + free_poly(poly1); + free_poly(poly2); + free_poly(poly3); +} + +/** + * @brief Test function 2 + * + * @details + * Polynomial 1 is 3 x^5 + 1 x^4 + 2 x^3 + -2 x^1 + 5 x^0 + * Polynomial 2 is 2 x^5 + 3 x^3 + 7 x^1 + 2 x^0 + * Resultant polynomial is 5 x^5 + 1 x^4 + 5 x^3 + 5 x^1 + 7 x^0 + * @returns void + */ +static void test2(struct term *poly1, struct term *poly2, struct term *poly3) +{ + printf("\n----Test 2----\n"); + printf("\nFirst Polynomial:\n"); // Defining the 1st polynomial + create_polynomial(&poly1, 3, 5); + create_polynomial(&poly1, 1, 4); + create_polynomial(&poly1, 2, 3); + create_polynomial(&poly1, -2, 1); + create_polynomial(&poly1, 5, 0); + + display_polynomial(poly1); + + printf("\nSecond Polynomial:\n"); // Defining the 2nd polynomial + create_polynomial(&poly2, 2, 5); + create_polynomial(&poly2, 3, 3); + create_polynomial(&poly2, 7, 1); + create_polynomial(&poly2, 2, 0); + + display_polynomial(poly2); + + poly_add(&poly3, poly1, poly2); // Adding the two polynomials + printf("\nResultant polynomial:\n"); + display_polynomial(poly3); + printf("\n"); + + // Frees memory space + free_poly(poly1); + free_poly(poly2); + free_poly(poly3); +} + +/** + * @brief Test function 3 + * + * @details + * Polynomial 1 is -12 x^0 + 8 x^1 + 4 x^3 + * Polynomial 2 is 5 x^0 + -13 x^1 + 3 x^3 + * Resultant polynomial is -7 x^0 + -5 x^1 + 7 x^3 + * @returns void + */ +static void test3(struct term *poly1, struct term *poly2, struct term *poly3) +{ + printf("\n----Test 3----\n"); + printf("\nFirst Polynomial:\n"); // Defining the 1st polynomial + create_polynomial(&poly1, -12, 0); + create_polynomial(&poly1, 8, 1); + create_polynomial(&poly1, 4, 3); + + display_polynomial(poly1); + + printf("\nSecond Polynomial:\n"); // Defining the 2nd polynomial + create_polynomial(&poly2, 5, 0); + create_polynomial(&poly2, -13, 1); + create_polynomial(&poly2, 3, 3); + + display_polynomial(poly2); + + poly_add(&poly3, poly1, poly2); // Adding the two polynomials + printf("\nResultant polynomial:\n"); + display_polynomial(poly3); + printf("\n"); + + // Frees memory space + free_poly(poly1); + free_poly(poly2); + free_poly(poly3); +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main(void) +{ + struct term *poly1 = NULL, *poly2 = NULL, *poly3 = NULL; + test1(poly1, poly2, poly3); + test2(poly1, poly2, poly3); + test3(poly1, poly2, poly3); + + return 0; +}