From 23c788d0c23ee16e423e070607ce3b9e05ad35e3 Mon Sep 17 00:00:00 2001 From: hugogogo Date: Thu, 7 May 2026 19:38:43 +0200 Subject: [PATCH] new struct for polynom --- README.md | 8 ++- headers/computorv1.h | 32 ++++++------ src/launcher.c | 67 +++++++++++++++++++------ src/main.c | 3 +- src/parser.c | 4 +- src/reducer.c | 64 +++++++++++++++++++----- src/solver.c | 8 +-- src/utils/errors.c | 6 +-- src/utils/print_enums.c | 12 ++--- src/utils/printer.c | 108 +++++++++++++++++++--------------------- 10 files changed, 191 insertions(+), 121 deletions(-) diff --git a/README.md b/README.md index f595256..1e734dc 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,9 @@ this project uses submodules (maybe recursively), so either : - EXPONENT // double 3. reduce -> polynom : - - 0 - - 1 - - 2 - - 3 - - ... + - sign + - coefficient + - exponent 4. print reduced form -> print reduced form -> if degree 1 : diff --git a/headers/computorv1.h b/headers/computorv1.h index c727933..c2651f4 100644 --- a/headers/computorv1.h +++ b/headers/computorv1.h @@ -1,5 +1,3 @@ -/* computorv1.h */ - #ifndef COMPUTORV1_H #define COMPUTORV1_H @@ -76,16 +74,16 @@ void lexerize(const char *input, s_token *tokens); typedef enum { - TERM_LEFT, // a in "a = b" - TERM_RIGHT, // b in "a = b" - TERM_END, // last term + TERM_LEFT, // a in "a = b" + TERM_RIGHT, // b in "a = b" + TERM_POS_END, // last term } e_term_position; typedef enum { - TERM_PLUS, // + - TERM_MINUS, // - - TERM_NULL, // null -> for the last term + TERM_PLUS = '+', // + + TERM_MINUS = '-', // - + TERM_SIGN_END, // last term } e_term_sign; typedef struct @@ -102,7 +100,14 @@ void parse(s_token *tokens, s_term *terms, int terms_count_max); * REDUCE.C */ -void reduce(s_term *terms, double *polynom); +typedef struct +{ + e_term_sign sign; + double coefficient; + int exponent; +} s_polynom; + +int reduce(s_term *terms, s_polynom *polynom, int max_exponent); /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SOLVE.C @@ -131,7 +136,7 @@ typedef struct double solution2; // first_term - second_term } s_solution; -void solve(const double *polynom, s_solution *solution); +void solve(const s_polynom *polynom, s_solution *solution); /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * UTILS/ERRORS.C @@ -155,8 +160,8 @@ const char *delta_sign_to_str(e_delta_sign sign); */ void print_debug(const char *description, ...); -void print_reduced_form(double *polynom, int max_exponent); -void print_degree(double *polynom, int max_exponent); +void print_reduced_form(s_polynom *polynom); +void print_degree(s_polynom *polynom, int max_exponent); /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * GLOBALS @@ -165,8 +170,7 @@ void print_degree(double *polynom, int max_exponent); extern char *input_g_err; extern s_token *tokens_g_err; extern s_term *terms_g_err; -extern double *polynom_g_err; -extern int polynom_len_g_err; +extern s_polynom *polynom_g_err; extern s_solution *solution_g_err; extern bool flag_debug_mode; extern bool flag_loop_mode; diff --git a/src/launcher.c b/src/launcher.c index 9a7dccb..900f0de 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -61,8 +61,8 @@ static void terms_fill_null(s_term *terms, size_t terms_count_prediction) { terms[i].coefficient = 0.0; terms[i].exponent = 0; - terms[i].position = TERM_END; - terms[i].sign = TERM_NULL; + terms[i].position = TERM_POS_END; + terms[i].sign = TERM_SIGN_END; i++; } } @@ -74,7 +74,7 @@ static int get_max_exponent(s_term *terms) i = 0; max_exponent = 0; - while (terms[i].position != TERM_END) + while (terms[i].position != TERM_POS_END) { if (terms[i].exponent > max_exponent) { @@ -86,14 +86,45 @@ static int get_max_exponent(s_term *terms) return max_exponent; } -static void polynom_fill_null(double *polynom, int len) +static int get_number_of_exponents(s_term *terms, int max_exponent) +{ + int i; + int nbr_of_exponent; + + int exponent_present[max_exponent]; + ft_bzero(exponent_present, sizeof(exponent_present)); + + // mark exponents as present + i = 0; + while (terms[i].position != TERM_POS_END) + { + exponent_present[terms[i].exponent] = 1; + i++; + } + + // Count unique exponents + nbr_of_exponent = 0; + i = 0; + while (i < max_exponent) + { + if (exponent_present[i] == 1) + nbr_of_exponent++; + i++; + } + + return nbr_of_exponent; +} + +static void polynom_fill_null(s_polynom *polynom, int len) { int i; i = 0; - while (i <= len) + while (i < len) { - polynom[i] = 0.0; + polynom[i].coefficient = 0.0; + polynom[i].exponent = 0; + polynom[i].sign = TERM_SIGN_END; i++; } } @@ -101,6 +132,8 @@ static void polynom_fill_null(double *polynom, int len) void launch_computorv1(char *input) { int max_exponent; + int nbr_of_exponents; + int degree; size_t arg_len; size_t terms_count_prediction; @@ -127,20 +160,22 @@ void launch_computorv1(char *input) // reduce max_exponent = get_max_exponent(terms); print_debug("-> max_exponent: %i\n\n", max_exponent); - double polynom[max_exponent + 1]; + nbr_of_exponents = get_number_of_exponents(terms, max_exponent); + print_debug("-> nbr_of_exponents: %i\n\n", nbr_of_exponents); + s_polynom polynom[nbr_of_exponents + 2]; // +1 for last term, +1 for the degree (eg. degree 2 means 3 terms) polynom_g_err = polynom; - polynom_len_g_err = max_exponent; - polynom_fill_null(polynom, max_exponent); - reduce(terms, polynom); + polynom_fill_null(polynom, nbr_of_exponents + 2); + degree = reduce(terms, polynom, max_exponent); + print_debug("-> degree: %i\n\n", degree); // print before solution - print_reduced_form(polynom, max_exponent); - print_degree(polynom, max_exponent); + print_reduced_form(polynom); + // print_degree(polynom, degree); - // solve - s_solution solution[1]; - solution_g_err = solution; - solve(polynom, solution); + // // solve + // s_solution solution[1]; + // solution_g_err = solution; + // solve(polynom, solution); // print solution diff --git a/src/main.c b/src/main.c index d6360fc..cc14f25 100644 --- a/src/main.c +++ b/src/main.c @@ -12,8 +12,7 @@ bool flag_beautify_mode; char *input_g_err; s_token *tokens_g_err; s_term *terms_g_err; -double *polynom_g_err; -int polynom_len_g_err; +s_polynom *polynom_g_err; s_solution *solution_g_err; /** diff --git a/src/parser.c b/src/parser.c index 8ca2911..9946a11 100644 --- a/src/parser.c +++ b/src/parser.c @@ -258,8 +258,8 @@ void parse(s_token *tokens, s_term *terms, int terms_count_max) // last token is TOKEN_END, and terms[] should have at least one more spot for the END term if (tokens[i].type == TOKEN_END && terms_count < terms_count_max) { - terms[terms_count].position = TERM_END; - terms[terms_count].sign = TERM_NULL; + terms[terms_count].position = TERM_POS_END; + terms[terms_count].sign = TERM_SIGN_END; terms[terms_count].coefficient = 0; terms[terms_count].exponent = 0; } diff --git a/src/reducer.c b/src/reducer.c index 453efb7..b7bbc9c 100644 --- a/src/reducer.c +++ b/src/reducer.c @@ -2,27 +2,67 @@ #include "computorv1.h" -void reduce(s_term *terms, double *polynom) +static double get_all_terms_with_exponent(s_term *terms, int exponent) { int i; - int exponent; - double tmp; + double coefficient; + int sign; i = 0; - while (terms[i].position != TERM_END) + coefficient = 0.0; + while (terms[i].sign != TERM_SIGN_END) { - - // get coefficient with left sign - tmp = terms[i].coefficient; - if (terms[i].position == TERM_RIGHT) + if (terms[i].exponent != exponent) { - tmp *= -1; + i++; + continue; } - // add coefficient to exponent - exponent = terms[i].exponent; - polynom[exponent] += tmp; + // sign + sign = terms[i].sign == TERM_PLUS ? 1 : -1; + if (terms[i].position == TERM_RIGHT) + sign *= -1; + // add coefficients + coefficient += terms[i].coefficient * sign; i++; } + + return coefficient; +} + +int reduce(s_term *terms, s_polynom *polynom, int max_exponent) +{ + int i; + double tmp_coefficient; + int degree; + + i = 0; + degree = 0; + while (max_exponent >= 0) + { + // if any terms contains this exponent, returns the addition of their coefficient + tmp_coefficient = get_all_terms_with_exponent(terms, max_exponent); + + // skip if coefficient is null or no exponent + if (tmp_coefficient == 0.0) + { + max_exponent--; + continue; + } + + // get degree + if (max_exponent > degree) + degree = max_exponent; + + // fill polynom + polynom[i].coefficient = tmp_coefficient; + polynom[i].exponent = max_exponent; + polynom[i].sign = ft_sign_f(tmp_coefficient) == 1 ? TERM_PLUS : TERM_MINUS; + + max_exponent--; + i++; + } + + return degree; } \ No newline at end of file diff --git a/src/solver.c b/src/solver.c index 9c11cf9..10e4284 100644 --- a/src/solver.c +++ b/src/solver.c @@ -83,16 +83,16 @@ static int find_gcd(double numerator, double denominator) double solution2; // first_term - second_term */ -void solve(const double *polynom, s_solution *solution) +void solve(const s_polynom *polynom, s_solution *solution) { double delta; double a; double b; double c; - a = polynom[2]; - b = polynom[1]; - c = polynom[0]; + a = polynom[2].coefficient; + b = polynom[1].coefficient; + c = polynom[0].coefficient; delta = b * b - 4 * a * c; solution->delta_sign = ft_sign_f(delta); solution->delta_absolute = ft_fabs(delta); diff --git a/src/utils/errors.c b/src/utils/errors.c index 12534cb..5c15530 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -44,7 +44,7 @@ static void print_context_terms() int i; i = 0; - while (terms_g_err[i].position != TERM_END) + while (terms_g_err[i].position != TERM_POS_END) { ft_dprintf(STDERR_FILENO, "term[%2i] - ", i); ft_dprintf(STDERR_FILENO, "%8s : %10s", "position", term_position_to_str(terms_g_err[i].position)); @@ -61,9 +61,9 @@ static void print_context_polynom() int i; i = 0; - while (i <= polynom_len_g_err) + while (polynom_g_err[i].sign != TERM_SIGN_END) { - dprintf(STDERR_FILENO, "polynom[%i]: %c -> %10g\n", i, i + 'a', polynom_g_err[i]); + dprintf(STDERR_FILENO, "polynom[%i] - sign: %15s(%c) - coefficient: %10g - exponent: %10i\n", i, term_sign_to_str(polynom_g_err[i].sign), polynom_g_err[i].sign, polynom_g_err[i].coefficient, polynom_g_err[i].exponent); i++; } ft_putchar_fd('\n', STDERR_FILENO); diff --git a/src/utils/print_enums.c b/src/utils/print_enums.c index b48afa1..d567315 100644 --- a/src/utils/print_enums.c +++ b/src/utils/print_enums.c @@ -37,25 +37,25 @@ const char *token_tag_to_str(e_token_tag enum_value) const char *term_position_to_str(e_term_position enum_value) { - if (enum_value > TERM_END || enum_value < TERM_LEFT) + if (enum_value > TERM_POS_END || enum_value < TERM_LEFT) return "invalid enum value"; - static const char *const term_position_str[TERM_END + 1] = { + static const char *const term_position_str[TERM_POS_END + 1] = { [TERM_LEFT] = "TERM_LEFT", [TERM_RIGHT] = "TERM_RIGHT", - [TERM_END] = "TERM_END"}; + [TERM_POS_END] = "TERM_POS_END"}; return term_position_str[enum_value]; } const char *term_sign_to_str(e_term_sign enum_value) { - if (enum_value > TERM_NULL || enum_value < TERM_PLUS) + if (enum_value > TERM_SIGN_END || enum_value < TERM_PLUS) return "invalid enum value"; - static const char *const term_sign_str[TERM_NULL + 1] = { + static const char *const term_sign_str[TERM_SIGN_END + 1] = { [TERM_PLUS] = "TERM_PLUS", [TERM_MINUS] = "TERM_MINUS", - [TERM_NULL] = "TERM_NULL"}; + [TERM_SIGN_END] = "TERM_SIGN_END"}; return term_sign_str[enum_value]; } diff --git a/src/utils/printer.c b/src/utils/printer.c index 94b6d02..9b4fa34 100644 --- a/src/utils/printer.c +++ b/src/utils/printer.c @@ -23,42 +23,42 @@ void print_debug(const char *description, ...) - [x] : ./computorv1 -b "-3x² + 2x -7 = x" Reduced form: -+ x - 7 = 0 */ -static void print_reduced_form_beautify(double *polynom, int max_exponent) +static void print_reduced_form_beautify(s_polynom *polynom) { int i; bool is_first_term; - double value; - int sign; + double coefficient; + int exponent; + char *default_form; + default_form = "0 "; ft_putstr("Reduced form: "); - i = max_exponent; + i = 0; is_first_term = true; - while (i >= 0) + while (polynom[i].sign != TERM_SIGN_END) { - value = ft_fabs(polynom[i]); - sign = ft_sign_f(polynom[i]); - // dprintf(STDERR_FILENO, "\nDEBUG: polynom[%i]: %g, sign: %i\n", i, value, sign); // debug + coefficient = ft_fabs(polynom[i].coefficient); + exponent = polynom[i].exponent; + // dprintf(STDERR_FILENO, "\nDEBUG: polynom[0].coefficient: %g, polynom[0].exponent: %i, polynom[0].sign: %c\n", polynom[0].coefficient, polynom[0].exponent, polynom[0].sign); // tmpdebug // if term is zero dont output - if (value == 0) + if (coefficient == 0.0) { - // ft_dprintf(STDERR_FILENO, "DEBUG: is 0\n"); // debug - i--; + // ft_dprintf(STDERR_FILENO, "DEBUG: is 0\n"); // tmpdebug + i++; continue; } - // ft_dprintf(STDERR_FILENO, "DEBUG: is not 0\n"); // debug + // ft_dprintf(STDERR_FILENO, "DEBUG: is not 0\n"); // tmpdebug + + // default_form is not nedded anymore since something will be printed + default_form = ""; // print sign - if (sign > 0) + // don't output '+' if is first term + if (!(polynom[i].sign == TERM_PLUS && is_first_term)) { - // don't output '+' if is first term - if (!is_first_term) - ft_putchar('+'); - } - else - { - ft_putchar('-'); + ft_putchar(polynom[i].sign); } // print term @@ -68,60 +68,55 @@ static void print_reduced_form_beautify(double *polynom, int max_exponent) } // for x⁰ - if (i == 0) + if (exponent == 0) { - printf("%g ", value); + printf("%g ", coefficient); } // for x¹ - if (i == 1) + if (exponent == 1) { - if (value == 1) + if (coefficient == 1) printf("x "); - if (value > 1) - printf("%gx ", value); + if (coefficient > 1) + printf("%gx ", coefficient); } // for x² - if (i >= 2) + if (exponent >= 2) { - if (value == 1) - printf("x%s ", ft_superscript(i + '0')); - if (value > 1) - printf("%gx%s ", value, ft_superscript(i + '0')); + if (coefficient == 1) + printf("x%s ", ft_superscript(exponent + '0')); + if (coefficient > 1) + printf("%gx%s ", coefficient, ft_superscript(exponent + '0')); } fflush(stdout); - i--; + i++; is_first_term = false; } - ft_putstr("= 0\n"); + ft_printf("%s= 0\n", default_form); } -void print_reduced_form(double *polynom, int max_exponent) +void print_reduced_form(s_polynom *polynom) { int i; bool is_first_term; if (flag_beautify_mode) - return print_reduced_form_beautify(polynom, max_exponent); + return print_reduced_form_beautify(polynom); // reduced form ft_putstr("Reduced form: "); - i = max_exponent; is_first_term = true; - while (i >= 0) + i = 0; + while (polynom[i].sign != TERM_SIGN_END) { // print sign - if (polynom[i] > 0) + // don't output '+' if is first term + if (!(polynom[i].sign == TERM_PLUS && is_first_term)) { - // don't output '+' if is first term - if (!is_first_term) - ft_putchar('+'); - } - else - { - ft_putchar('-'); + ft_putchar(polynom[i].sign); } // print term @@ -129,40 +124,39 @@ void print_reduced_form(double *polynom, int max_exponent) { ft_putchar(' '); } - printf("%g * x^%i ", ft_fabs(polynom[i]), i); + printf("%g * x^%i ", ft_fabs(polynom[i].coefficient), polynom[i].exponent); fflush(stdout); - i--; + i++; is_first_term = false; } ft_putstr("= 0\n"); } -void print_degree(double *polynom, int max_exponent) +void print_degree(s_polynom *polynom, int degree) { - - if (max_exponent == 0) + if (degree == 0) { - if (polynom[0] == 0) + if (polynom[0].coefficient == 0) { stop_errors("Any real number is a solution.\n"); } - else if (polynom[0] != 0) + else if (polynom[0].coefficient != 0) { stop_errors("No solution.\n"); } } - else if (max_exponent == 1) + else if (degree == 1) { - ft_printf("Polynomial degree: %i\n", max_exponent); + ft_printf("Polynomial degree: %i\n", degree); } - else if (max_exponent == 2) + else if (degree == 2) { - ft_printf("Polynomial degree: %i\n", max_exponent); + ft_printf("Polynomial degree: %i\n", degree); } else { - ft_printf("Polynomial degree: %i\n", max_exponent); + ft_printf("Polynomial degree: %i\n", degree); stop_errors("The polynomial degree is strictly greater than 2, I can't solve.\n"); } } \ No newline at end of file