new struct for polynom

This commit is contained in:
hugogogo
2026-05-07 19:38:43 +02:00
parent f62a6fe94f
commit 23c788d0c2
10 changed files with 191 additions and 121 deletions

View File

@@ -35,11 +35,9 @@ this project uses submodules (maybe recursively), so either :
- EXPONENT // double - EXPONENT // double
3. reduce 3. reduce
-> polynom : -> polynom :
- 0 - sign
- 1 - coefficient
- 2 - exponent
- 3
- ...
4. print reduced form 4. print reduced form
-> print reduced form -> print reduced form
-> if degree 1 : -> if degree 1 :

View File

@@ -1,5 +1,3 @@
/* computorv1.h */
#ifndef COMPUTORV1_H #ifndef COMPUTORV1_H
#define COMPUTORV1_H #define COMPUTORV1_H
@@ -76,16 +74,16 @@ void lexerize(const char *input, s_token *tokens);
typedef enum typedef enum
{ {
TERM_LEFT, // a in "a = b" TERM_LEFT, // a in "a = b"
TERM_RIGHT, // b in "a = b" TERM_RIGHT, // b in "a = b"
TERM_END, // last term TERM_POS_END, // last term
} e_term_position; } e_term_position;
typedef enum typedef enum
{ {
TERM_PLUS, // + TERM_PLUS = '+', // +
TERM_MINUS, // - TERM_MINUS = '-', // -
TERM_NULL, // null -> for the last term TERM_SIGN_END, // last term
} e_term_sign; } e_term_sign;
typedef struct typedef struct
@@ -102,7 +100,14 @@ void parse(s_token *tokens, s_term *terms, int terms_count_max);
* REDUCE.C * 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 * SOLVE.C
@@ -131,7 +136,7 @@ typedef struct
double solution2; // first_term - second_term double solution2; // first_term - second_term
} s_solution; } s_solution;
void solve(const double *polynom, s_solution *solution); void solve(const s_polynom *polynom, s_solution *solution);
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* UTILS/ERRORS.C * 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_debug(const char *description, ...);
void print_reduced_form(double *polynom, int max_exponent); void print_reduced_form(s_polynom *polynom);
void print_degree(double *polynom, int max_exponent); void print_degree(s_polynom *polynom, int max_exponent);
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* GLOBALS * GLOBALS
@@ -165,8 +170,7 @@ void print_degree(double *polynom, int max_exponent);
extern char *input_g_err; extern char *input_g_err;
extern s_token *tokens_g_err; extern s_token *tokens_g_err;
extern s_term *terms_g_err; extern s_term *terms_g_err;
extern double *polynom_g_err; extern s_polynom *polynom_g_err;
extern int polynom_len_g_err;
extern s_solution *solution_g_err; extern s_solution *solution_g_err;
extern bool flag_debug_mode; extern bool flag_debug_mode;
extern bool flag_loop_mode; extern bool flag_loop_mode;

View File

@@ -61,8 +61,8 @@ static void terms_fill_null(s_term *terms, size_t terms_count_prediction)
{ {
terms[i].coefficient = 0.0; terms[i].coefficient = 0.0;
terms[i].exponent = 0; terms[i].exponent = 0;
terms[i].position = TERM_END; terms[i].position = TERM_POS_END;
terms[i].sign = TERM_NULL; terms[i].sign = TERM_SIGN_END;
i++; i++;
} }
} }
@@ -74,7 +74,7 @@ static int get_max_exponent(s_term *terms)
i = 0; i = 0;
max_exponent = 0; max_exponent = 0;
while (terms[i].position != TERM_END) while (terms[i].position != TERM_POS_END)
{ {
if (terms[i].exponent > max_exponent) if (terms[i].exponent > max_exponent)
{ {
@@ -86,14 +86,45 @@ static int get_max_exponent(s_term *terms)
return max_exponent; 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; int i;
i = 0; 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++; i++;
} }
} }
@@ -101,6 +132,8 @@ static void polynom_fill_null(double *polynom, int len)
void launch_computorv1(char *input) void launch_computorv1(char *input)
{ {
int max_exponent; int max_exponent;
int nbr_of_exponents;
int degree;
size_t arg_len; size_t arg_len;
size_t terms_count_prediction; size_t terms_count_prediction;
@@ -127,20 +160,22 @@ void launch_computorv1(char *input)
// reduce // reduce
max_exponent = get_max_exponent(terms); max_exponent = get_max_exponent(terms);
print_debug("-> max_exponent: %i\n\n", max_exponent); 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_g_err = polynom;
polynom_len_g_err = max_exponent; polynom_fill_null(polynom, nbr_of_exponents + 2);
polynom_fill_null(polynom, max_exponent); degree = reduce(terms, polynom, max_exponent);
reduce(terms, polynom); print_debug("-> degree: %i\n\n", degree);
// print before solution // print before solution
print_reduced_form(polynom, max_exponent); print_reduced_form(polynom);
print_degree(polynom, max_exponent); // print_degree(polynom, degree);
// solve // // solve
s_solution solution[1]; // s_solution solution[1];
solution_g_err = solution; // solution_g_err = solution;
solve(polynom, solution); // solve(polynom, solution);
// print solution // print solution

View File

@@ -12,8 +12,7 @@ bool flag_beautify_mode;
char *input_g_err; char *input_g_err;
s_token *tokens_g_err; s_token *tokens_g_err;
s_term *terms_g_err; s_term *terms_g_err;
double *polynom_g_err; s_polynom *polynom_g_err;
int polynom_len_g_err;
s_solution *solution_g_err; s_solution *solution_g_err;
/** /**

View File

@@ -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 // 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) if (tokens[i].type == TOKEN_END && terms_count < terms_count_max)
{ {
terms[terms_count].position = TERM_END; terms[terms_count].position = TERM_POS_END;
terms[terms_count].sign = TERM_NULL; terms[terms_count].sign = TERM_SIGN_END;
terms[terms_count].coefficient = 0; terms[terms_count].coefficient = 0;
terms[terms_count].exponent = 0; terms[terms_count].exponent = 0;
} }

View File

@@ -2,27 +2,67 @@
#include "computorv1.h" #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 i;
int exponent; double coefficient;
double tmp; int sign;
i = 0; i = 0;
while (terms[i].position != TERM_END) coefficient = 0.0;
while (terms[i].sign != TERM_SIGN_END)
{ {
if (terms[i].exponent != exponent)
// get coefficient with left sign
tmp = terms[i].coefficient;
if (terms[i].position == TERM_RIGHT)
{ {
tmp *= -1; i++;
continue;
} }
// add coefficient to exponent // sign
exponent = terms[i].exponent; sign = terms[i].sign == TERM_PLUS ? 1 : -1;
polynom[exponent] += tmp; if (terms[i].position == TERM_RIGHT)
sign *= -1;
// add coefficients
coefficient += terms[i].coefficient * sign;
i++; 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;
} }

View File

@@ -83,16 +83,16 @@ static int find_gcd(double numerator, double denominator)
double solution2; // first_term - second_term 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 delta;
double a; double a;
double b; double b;
double c; double c;
a = polynom[2]; a = polynom[2].coefficient;
b = polynom[1]; b = polynom[1].coefficient;
c = polynom[0]; c = polynom[0].coefficient;
delta = b * b - 4 * a * c; delta = b * b - 4 * a * c;
solution->delta_sign = ft_sign_f(delta); solution->delta_sign = ft_sign_f(delta);
solution->delta_absolute = ft_fabs(delta); solution->delta_absolute = ft_fabs(delta);

View File

@@ -44,7 +44,7 @@ static void print_context_terms()
int i; int i;
i = 0; 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, "term[%2i] - ", i);
ft_dprintf(STDERR_FILENO, "%8s : %10s", "position", term_position_to_str(terms_g_err[i].position)); 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; int i;
i = 0; 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++; i++;
} }
ft_putchar_fd('\n', STDERR_FILENO); ft_putchar_fd('\n', STDERR_FILENO);

View File

@@ -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) 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"; 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_LEFT] = "TERM_LEFT",
[TERM_RIGHT] = "TERM_RIGHT", [TERM_RIGHT] = "TERM_RIGHT",
[TERM_END] = "TERM_END"}; [TERM_POS_END] = "TERM_POS_END"};
return term_position_str[enum_value]; return term_position_str[enum_value];
} }
const char *term_sign_to_str(e_term_sign 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"; 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_PLUS] = "TERM_PLUS",
[TERM_MINUS] = "TERM_MINUS", [TERM_MINUS] = "TERM_MINUS",
[TERM_NULL] = "TERM_NULL"}; [TERM_SIGN_END] = "TERM_SIGN_END"};
return term_sign_str[enum_value]; return term_sign_str[enum_value];
} }

View File

@@ -23,42 +23,42 @@ void print_debug(const char *description, ...)
- [x] : ./computorv1 -b "-3x² + 2x -7 = x" - [x] : ./computorv1 -b "-3x² + 2x -7 = x"
Reduced form: -+ x - 7 = 0 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; int i;
bool is_first_term; bool is_first_term;
double value; double coefficient;
int sign; int exponent;
char *default_form;
default_form = "0 ";
ft_putstr("Reduced form: "); ft_putstr("Reduced form: ");
i = max_exponent; i = 0;
is_first_term = true; is_first_term = true;
while (i >= 0) while (polynom[i].sign != TERM_SIGN_END)
{ {
value = ft_fabs(polynom[i]); coefficient = ft_fabs(polynom[i].coefficient);
sign = ft_sign_f(polynom[i]); exponent = polynom[i].exponent;
// dprintf(STDERR_FILENO, "\nDEBUG: polynom[%i]: %g, sign: %i\n", i, value, sign); // debug // 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 term is zero dont output
if (value == 0) if (coefficient == 0.0)
{ {
// ft_dprintf(STDERR_FILENO, "DEBUG: is 0\n"); // debug // ft_dprintf(STDERR_FILENO, "DEBUG: is 0\n"); // tmpdebug
i--; i++;
continue; 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 // 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 ft_putchar(polynom[i].sign);
if (!is_first_term)
ft_putchar('+');
}
else
{
ft_putchar('-');
} }
// print term // print term
@@ -68,60 +68,55 @@ static void print_reduced_form_beautify(double *polynom, int max_exponent)
} }
// for x⁰ // for x⁰
if (i == 0) if (exponent == 0)
{ {
printf("%g ", value); printf("%g ", coefficient);
} }
// for x¹ // for x¹
if (i == 1) if (exponent == 1)
{ {
if (value == 1) if (coefficient == 1)
printf("x "); printf("x ");
if (value > 1) if (coefficient > 1)
printf("%gx ", value); printf("%gx ", coefficient);
} }
// for x² // for x²
if (i >= 2) if (exponent >= 2)
{ {
if (value == 1) if (coefficient == 1)
printf("x%s ", ft_superscript(i + '0')); printf("x%s ", ft_superscript(exponent + '0'));
if (value > 1) if (coefficient > 1)
printf("%gx%s ", value, ft_superscript(i + '0')); printf("%gx%s ", coefficient, ft_superscript(exponent + '0'));
} }
fflush(stdout); fflush(stdout);
i--; i++;
is_first_term = false; 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; int i;
bool is_first_term; bool is_first_term;
if (flag_beautify_mode) if (flag_beautify_mode)
return print_reduced_form_beautify(polynom, max_exponent); return print_reduced_form_beautify(polynom);
// reduced form // reduced form
ft_putstr("Reduced form: "); ft_putstr("Reduced form: ");
i = max_exponent;
is_first_term = true; is_first_term = true;
while (i >= 0) i = 0;
while (polynom[i].sign != TERM_SIGN_END)
{ {
// print sign // 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 ft_putchar(polynom[i].sign);
if (!is_first_term)
ft_putchar('+');
}
else
{
ft_putchar('-');
} }
// print term // print term
@@ -129,40 +124,39 @@ void print_reduced_form(double *polynom, int max_exponent)
{ {
ft_putchar(' '); 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); fflush(stdout);
i--; i++;
is_first_term = false; is_first_term = false;
} }
ft_putstr("= 0\n"); ft_putstr("= 0\n");
} }
void print_degree(double *polynom, int max_exponent) void print_degree(s_polynom *polynom, int degree)
{ {
if (degree == 0)
if (max_exponent == 0)
{ {
if (polynom[0] == 0) if (polynom[0].coefficient == 0)
{ {
stop_errors("Any real number is a solution.\n"); 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"); 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 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"); stop_errors("The polynomial degree is strictly greater than 2, I can't solve.\n");
} }
} }