LCOV - code coverage report
Current view: top level - poly - poly.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 118 129 91.5 %
Date: 2024-11-25 23:11:58 Functions: 5 5 100.0 %

          Line data    Source code
       1             : #include "poly.h"
       2             : #include <ctype.h>
       3             : #include <stdio.h>
       4             : #include <stdlib.h>
       5             : 
       6             : // struct to store each term, so coeff*x^{exp}
       7             : typedef struct term {
       8             :   int coeff;
       9             :   int exp;
      10             :   struct term *next;
      11             : } term_t;
      12             : 
      13             : struct poly_t {
      14             :   term_t *first;
      15             : };
      16             : 
      17           6 : void free_poly(poly_t *poly) {
      18           6 :   if (poly == NULL)
      19           0 :     return;
      20           6 :   term_t *term = poly->first;
      21             :   term_t *next;
      22             : 
      23          26 :   while (term != NULL) {
      24          20 :     next = term->next;
      25          20 :     term->next = NULL;
      26          20 :     free(term);
      27          20 :     term = next;
      28             :   }
      29           6 :   poly->first = NULL;
      30           6 :   free(poly);
      31           6 : }
      32             : 
      33          22 : void add_term(poly_t *poly, int coeff, int exp) {
      34             :   // If coefficient is zero, don't add the term
      35          22 :   if (coeff == 0) {
      36           0 :     return;
      37             :   }
      38             : 
      39             :   // If the list is empty, create the first term
      40          22 :   if (!poly->first) {
      41           6 :     term_t *new_term = malloc(sizeof(term_t));
      42           6 :     new_term->coeff = coeff;
      43           6 :     new_term->exp = exp;
      44           6 :     new_term->next = NULL;
      45           6 :     poly->first = new_term;
      46           6 :     return;
      47             :   }
      48             : 
      49             :   // Check if there's an existing term with the same exponent
      50          16 :   term_t *current = poly->first;
      51          16 :   term_t *prev = NULL;
      52             : 
      53          48 :   while (current != NULL) {
      54          34 :     if (current->exp == exp) {
      55             :       // Combine coefficients of like terms
      56           2 :       current->coeff += coeff;
      57             : 
      58             :       // If the coefficient becomes zero, remove the term
      59           2 :       if (current->coeff == 0) {
      60           0 :         if (prev == NULL) {
      61           0 :           poly->first = current->next;
      62           0 :         } else {
      63           0 :           prev->next = current->next;
      64             :         }
      65           0 :         free(current);
      66           0 :       }
      67           2 :       return;
      68             :     }
      69             : 
      70          32 :     prev = current;
      71          32 :     current = current->next;
      72             :   }
      73             : 
      74             :   // If no term with the same exponent is found, add a new term
      75          14 :   term_t *new_term = malloc(sizeof(term_t));
      76          14 :   new_term->coeff = coeff;
      77          14 :   new_term->exp = exp;
      78          14 :   new_term->next = NULL;
      79             : 
      80          14 :   current = poly->first;
      81          14 :   prev = NULL;
      82          43 :   while (current != NULL && current->exp > exp) {
      83          29 :     prev = current;
      84          29 :     current = current->next;
      85             :   }
      86             : 
      87          14 :   if (prev == NULL) {
      88           0 :     new_term->next = poly->first;
      89           0 :     poly->first = new_term;
      90           0 :   } else {
      91          14 :     new_term->next = current;
      92          14 :     prev->next = new_term;
      93             :   }
      94          22 : }
      95             : 
      96           2 : poly_t *mul(poly_t *a, poly_t *b) {
      97           2 :   term_t *at = a->first;
      98           2 :   term_t *bt = b->first;
      99             :   int coeff, exp;
     100             : 
     101           2 :   poly_t *r = malloc(sizeof(poly_t));
     102           2 :   r->first = NULL;
     103             : 
     104           7 :   while (at != NULL) {
     105          17 :     while (bt != NULL) {
     106          12 :       coeff = at->coeff * bt->coeff;
     107          12 :       exp = at->exp + bt->exp;
     108          12 :       add_term(r, coeff, exp);
     109          12 :       bt = bt->next;
     110             :     }
     111           5 :     at = at->next;
     112           5 :     bt = b->first;
     113             :   }
     114           2 :   return r;
     115             : }
     116             : 
     117           4 : poly_t *new_poly_from_string(const char *str) {
     118           4 :   poly_t *poly = malloc(sizeof(poly_t));
     119           4 :   poly->first = NULL;
     120             : 
     121           4 :   const char *s = str;
     122           4 :   char sign = '+';
     123           4 :   int num = 0;
     124           4 :   int coeff = 0;
     125           4 :   int exp = 0;
     126             : 
     127          49 :   while (*s) {
     128          45 :     switch (*s) {
     129             :     case '-':
     130             :     case '+':
     131           6 :       sign = *s;
     132           6 :       s++;
     133           6 :       break;
     134             :     case 'x':
     135           6 :       if (num == 0) {
     136           2 :         num = 1; // no coefficient, but x is present so it is 1.
     137           2 :       }
     138           6 :       coeff = (sign == '-') ? -num : num;
     139           6 :       exp = 1; // at least one x present.
     140           6 :       num = 0;
     141           6 :       s++;
     142           6 :       break;
     143             : 
     144             :     case ' ':
     145             :       // c is 0 => don't need to add new term.
     146          12 :       if (coeff == 0) {
     147           6 :         s++;
     148           6 :         break;
     149             :       }
     150             :       // update e if a number has been found.
     151           6 :       if (num != 0)
     152           3 :         exp = num;
     153             : 
     154             :       // add term to poly.
     155           6 :       add_term(poly, coeff, exp);
     156             :       // reset state.
     157           6 :       sign = '+';
     158           6 :       coeff = 0;
     159           6 :       exp = 0;
     160           6 :       num = 0;
     161           6 :       s++;
     162           6 :       break;
     163             : 
     164             :     default:
     165          21 :       if (isdigit(*s)) {
     166          18 :         num = 10 * num + (*s - '0');
     167          18 :       }
     168          21 :       s++;
     169          21 :       break;
     170             :     }
     171             :   }
     172             :   // end of string reached, add term if possible.
     173           4 :   if (num != 0) {
     174           4 :     add_term(poly, num, exp);
     175           4 :   }
     176             : 
     177           4 :   return poly;
     178             : }
     179             : 
     180           6 : void print_poly(poly_t *poly) {
     181           6 :   term_t *term = poly->first;
     182           6 :   int first = 1; // Flag to handle the first term.
     183             : 
     184          26 :   while (term != NULL) {
     185          20 :     char sign = (term->coeff > 0) ? '+' : '-';
     186          20 :     int coeff = abs(term->coeff);
     187          20 :     int exp = term->exp;
     188             : 
     189             :     // Print sign if not first element, since first is always positive.
     190          20 :     if (!first) {
     191          14 :       printf(" %c ", sign);
     192          14 :     } else {
     193           6 :       first = 0;
     194             :     }
     195          20 :     if (coeff > 1 || exp == 0)
     196          18 :       printf("%d", coeff);
     197          20 :     if (exp > 0)
     198          14 :       printf("x");
     199          20 :     if (exp > 1)
     200           9 :       printf("^%d", exp);
     201             : 
     202          20 :     term = term->next; // Move to the next term
     203             :   }
     204           6 :   printf("\n");
     205           6 : }

Generated by: LCOV version 1.15