new struct for polynom
This commit is contained in:
@@ -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 :
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user