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
3. reduce
-> polynom :
- 0
- 1
- 2
- 3
- ...
- sign
- coefficient
- exponent
4. print reduced form
-> print reduced form
-> if degree 1 :

View File

@@ -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;

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].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

View File

@@ -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;
/**

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
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;
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);

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)
{
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];
}

View File

@@ -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");
}
}