init solver
This commit is contained in:
15
Makefile
15
Makefile
@@ -42,6 +42,7 @@ SRCS = main.c \
|
||||
lexer.c \
|
||||
parser.c \
|
||||
reducer.c \
|
||||
solver.c \
|
||||
errors.c \
|
||||
printer.c \
|
||||
print_enums.c
|
||||
@@ -98,23 +99,23 @@ $(NAME): $(OBJS)
|
||||
$(CC) $(OBJS) -o $@ $(LFLAGS)
|
||||
|
||||
run: $(NAME)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n2. run without flag \n"$(RESET)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n1. run without flag \n"$(RESET)
|
||||
-./$(NAME) "3 * x^2 + 5 * x^1 - 2 * x^0 = 5 * x^1"
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n1. run with flag '-d' as last \n"$(RESET)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n2. run with flag '-d' as last \n"$(RESET)
|
||||
-./$(NAME) "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5 * x^1" -d
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n3. run with flag '-d' as first \n"$(RESET)
|
||||
-./$(NAME) -d "3 * x^2 + 2 * x^2 = 5 * x^1"
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n4. run with wrong flag '-e' SHOULD FAIL \n"$(RESET)
|
||||
-./$(NAME) -d -e "3 * x^2 + 2 * x - 7 * x^4 = 1 * x^4"
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n3. run with free form \n"$(RESET)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n5. run with free form \n"$(RESET)
|
||||
-./$(NAME) -d "3*x^2 + 2x = 0"
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n1. run with float coefficient \n"$(RESET)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n6. run with float coefficient \n"$(RESET)
|
||||
-./$(NAME) -d "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5.123 * x^1"
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n1. run with float exponent SHOULD FAILS \n"$(RESET)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n7. run with float exponent SHOULD FAILS \n"$(RESET)
|
||||
-./$(NAME) -d "3.4 * x^2 + 1 * x^1 - 2.0 * x^0 = 5 * x^1.2"
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n4. run with power 4 \n"$(RESET)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n8. run with power 4 \n"$(RESET)
|
||||
-./$(NAME) -d "3x^2 + 2x -7x^4 = x^4"
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n5. run with utf8 \n"$(RESET)
|
||||
@echo $(B_PURPLE)"\n---------------------------------------------\n9. run with utf8 \n"$(RESET)
|
||||
-./$(NAME) -d "3x² + 2x -7x³ = x³"
|
||||
|
||||
clean:
|
||||
|
||||
19
README.md
19
README.md
@@ -44,4 +44,21 @@ this project uses submodules (maybe recursively), so either :
|
||||
5. find degree
|
||||
6. print degree
|
||||
7. solve
|
||||
8. print solution
|
||||
-> discriminant : Δ = b² - 4ac
|
||||
-> Δ > 0 -> 2 solutions : x = ( -b / 2a ) +- ( √|Δ| / 2a )
|
||||
-> Δ == 0 -> : x = ( -b / 2a )
|
||||
-> Δ < 0 -> 2 solutions : x = ( -b / 2a ) +- i( √|Δ| / 2a )
|
||||
-> solution :
|
||||
- delta_sign; // + or -
|
||||
- delta_absolute; // |Δ|
|
||||
- first_term_pgcd; // pgcd(b, 2a)
|
||||
- first_term_numerator; // -b / pgcd
|
||||
- first_term_denominator; // 2a / pgcd
|
||||
- first_term; // double (-b / 2a)
|
||||
- second_term_pgcd; // pgcd(√|Δ|, 2a)
|
||||
- second_term_numerator; // √|Δ| / pgcd
|
||||
- second_term_denominator; // 2a / pgcd
|
||||
- second_term; // double (√|Δ| / 2a)
|
||||
- double solution1; // first_term + second_term
|
||||
- double solution2; // first_term - second_term
|
||||
8. print solution
|
||||
|
||||
@@ -66,7 +66,7 @@ typedef struct
|
||||
};
|
||||
} s_token;
|
||||
|
||||
int lexerize(const char *input, s_token *tokens);
|
||||
void lexerize(const char *input, s_token *tokens);
|
||||
|
||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* PARSER.C
|
||||
@@ -94,7 +94,7 @@ typedef struct
|
||||
int exponent;
|
||||
} s_term;
|
||||
|
||||
int parse(s_token *tokens, s_term *terms, int terms_count_max);
|
||||
void parse(s_token *tokens, s_term *terms, int terms_count_max);
|
||||
|
||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* REDUCE.C
|
||||
@@ -102,6 +102,35 @@ int parse(s_token *tokens, s_term *terms, int terms_count_max);
|
||||
|
||||
void reduce(s_term *terms, double *polynom);
|
||||
|
||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* SOLVE.C
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DELTA_PLUS, // +
|
||||
DELTA_MINUS, // -
|
||||
DELTA_ZERO, // 0
|
||||
} e_delta_sign;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
e_delta_sign delta_sign; // DELTA_PLUS or DELTA_MINUS or DELTA_ZERO
|
||||
double delta_absolute; // |Δ| == |b² - 4ac|
|
||||
int first_term_pgcd; // pgcd(b, 2a)
|
||||
int first_term_numerator; // -b / pgcd
|
||||
int first_term_denominator; // 2a / pgcd
|
||||
double first_term; // double (-b / 2a)
|
||||
int second_term_pgcd; // pgcd(√|Δ|, 2a)
|
||||
int second_term_numerator; // √|Δ| / pgcd
|
||||
int second_term_denominator; // 2a / pgcd
|
||||
double second_term; // double (√|Δ| / 2a)
|
||||
double solution1; // first_term + second_term
|
||||
double solution2; // first_term - second_term
|
||||
} s_solution;
|
||||
|
||||
void solve(const double *polynom, s_solution *solution);
|
||||
|
||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* UTILS/ERRORS.C
|
||||
*/
|
||||
@@ -117,6 +146,7 @@ const char *token_type_to_str(e_token_type type);
|
||||
const char *token_tag_to_str(e_token_tag tag);
|
||||
const char *term_position_to_str(e_term_position pos);
|
||||
const char *term_sign_to_str(e_term_sign sign);
|
||||
const char *delta_sign_to_str(e_delta_sign sign);
|
||||
|
||||
/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
* UTILS/PRINTER.C
|
||||
@@ -135,5 +165,6 @@ extern double *polynom_g_err;
|
||||
extern int polynom_len_g_err;
|
||||
extern bool flag_debug_mode;
|
||||
extern bool flag_loop_mode;
|
||||
extern s_solution *solution_g_err;
|
||||
|
||||
#endif
|
||||
@@ -100,7 +100,6 @@ static void polynom_fill_null(double *polynom, int len)
|
||||
|
||||
void launch_computorv1(char *input)
|
||||
{
|
||||
int ret;
|
||||
int max_exponent;
|
||||
size_t arg_len;
|
||||
size_t terms_count_prediction;
|
||||
@@ -115,11 +114,7 @@ void launch_computorv1(char *input)
|
||||
s_token tokens[arg_len];
|
||||
tokens_g_err = tokens;
|
||||
tokens_fill_null(tokens, arg_len);
|
||||
ret = lexerize(input, tokens);
|
||||
if (ret == 0)
|
||||
{
|
||||
stop_errors("lexer returned 0 token");
|
||||
}
|
||||
lexerize(input, tokens);
|
||||
|
||||
// parse
|
||||
terms_count_prediction = count_any_of(input, "-+=") + 2; // +1 for first term that can have no leading '+', +1 for last term == NULL
|
||||
@@ -127,11 +122,7 @@ void launch_computorv1(char *input)
|
||||
s_term terms[terms_count_prediction];
|
||||
terms_g_err = terms;
|
||||
terms_fill_null(terms, terms_count_prediction);
|
||||
ret = parse(tokens, terms, terms_count_prediction);
|
||||
if (ret == 0)
|
||||
{
|
||||
stop_errors("parser returned 0 term");
|
||||
}
|
||||
parse(tokens, terms, terms_count_prediction);
|
||||
|
||||
// reduce
|
||||
max_exponent = get_max_exponent(terms) + 1;
|
||||
@@ -142,6 +133,11 @@ void launch_computorv1(char *input)
|
||||
reduce(terms, polynom);
|
||||
|
||||
// solve
|
||||
s_solution solution[1];
|
||||
solution_g_err = solution;
|
||||
solve(polynom, solution);
|
||||
|
||||
// print solution
|
||||
|
||||
// debug
|
||||
print_state();
|
||||
|
||||
@@ -215,7 +215,7 @@ static bool token_is_equal(const char *input, int input_pos, int *token_size)
|
||||
/**
|
||||
* LEXER
|
||||
*/
|
||||
int lexerize(const char *input, s_token *tokens)
|
||||
void lexerize(const char *input, s_token *tokens)
|
||||
{
|
||||
int tokens_count;
|
||||
int input_pos;
|
||||
@@ -308,6 +308,4 @@ int lexerize(const char *input, s_token *tokens)
|
||||
tokens[tokens_count].type = TOKEN_END;
|
||||
tokens[tokens_count].tag = TOKEN_NO_TAG;
|
||||
tokens[tokens_count].value_char = '\0';
|
||||
|
||||
return tokens_count;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ s_token *tokens_g_err;
|
||||
s_term *terms_g_err;
|
||||
double *polynom_g_err;
|
||||
int polynom_len_g_err;
|
||||
s_solution *solution_g_err;
|
||||
|
||||
/**
|
||||
* PROGRAM
|
||||
@@ -91,6 +92,8 @@ static void launch_stdin_loop()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
// for the moment it does not work since errors exit
|
||||
launch_stdin();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ static void check_variables(s_token *tokens)
|
||||
}
|
||||
}
|
||||
|
||||
int parse(s_token *tokens, s_term *terms, int terms_count_max)
|
||||
void parse(s_token *tokens, s_term *terms, int terms_count_max)
|
||||
{
|
||||
int i;
|
||||
int terms_count;
|
||||
@@ -265,6 +265,4 @@ int parse(s_token *tokens, s_term *terms, int terms_count_max)
|
||||
{
|
||||
stop_errors("terms_count: %i, terms_count_max: %i, tokens[%i].type: %s", terms_count, terms_count_max, i, token_type_to_str(tokens[i].type));
|
||||
}
|
||||
|
||||
return terms_count;
|
||||
}
|
||||
50
src/solver.c
Normal file
50
src/solver.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/* solver.c */
|
||||
|
||||
#include "computorv1.h"
|
||||
|
||||
/*
|
||||
e_delta_sign delta_sign; // DELTA_PLUS or DELTA_MINUS or DELTA_ZERO
|
||||
double delta_absolute; // |Δ| == |b² - 4ac|
|
||||
int first_term_pgcd; // pgcd(b, 2a)
|
||||
int first_term_numerator; // -b / pgcd
|
||||
int first_term_denominator; // 2a / pgcd
|
||||
double first_term; // double (-b / 2a)
|
||||
int second_term_pgcd; // pgcd(√|Δ|, 2a)
|
||||
int second_term_numerator; // √|Δ| / pgcd
|
||||
int second_term_denominator; // 2a / pgcd
|
||||
double second_term; // double (√|Δ| / 2a)
|
||||
double solution1; // first_term + second_term
|
||||
double solution2; // first_term - second_term
|
||||
*/
|
||||
|
||||
void solve(const double *polynom, s_solution *solution)
|
||||
{
|
||||
double delta;
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
|
||||
a = polynom[2];
|
||||
b = polynom[1];
|
||||
c = polynom[0];
|
||||
delta = b * b - 4 * a * c;
|
||||
solution->delta_sign = ft_sign(delta);
|
||||
solution->delta_absolute = ft_abs(delta);
|
||||
// solution->first_term_pgcd = find_pgcd(b, 2 * a);
|
||||
// solution->first_term_numerator = ;
|
||||
// solution->first_term_denominator = ;
|
||||
// solution->first_term = ;
|
||||
// solution->second_term_pgcd = ;
|
||||
// solution->second_term_numerator = ;
|
||||
// solution->second_term_denominator = ;
|
||||
// solution->second_term = ;
|
||||
// solution->solution1 = solution->first_term;
|
||||
// if (solution->delta_sign == DELTA_ZERO)
|
||||
// {
|
||||
// solution->solution2 = ;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// solution->solution2 = 0.0;
|
||||
// }
|
||||
}
|
||||
@@ -15,33 +15,9 @@ static void print_context_tokens()
|
||||
i = 0;
|
||||
while (tokens_g_err[i].type != TOKEN_END)
|
||||
{
|
||||
ft_dprintf(STDERR_FILENO, "token[%2i] - type : ", i);
|
||||
|
||||
if (tokens_g_err[i].type == TOKEN_VARIABLE)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_VARIABLE");
|
||||
else if (tokens_g_err[i].type == TOKEN_NUMBER_INT)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_NUMBER_INT");
|
||||
else if (tokens_g_err[i].type == TOKEN_NUMBER_INT_SUPER)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_NUMBER_INT_SUPER");
|
||||
else if (tokens_g_err[i].type == TOKEN_NUMBER_DOUBLE)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_NUMBER_DOUBLE");
|
||||
else if (tokens_g_err[i].type == TOKEN_POWER)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_POWER");
|
||||
else if (tokens_g_err[i].type == TOKEN_SIGN_PLUS)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_SIGN_PLUS");
|
||||
else if (tokens_g_err[i].type == TOKEN_SIGN_MINUS)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_SIGN_MINUS");
|
||||
else if (tokens_g_err[i].type == TOKEN_FACTOR_MULT)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_FACTOR_MULT");
|
||||
else if (tokens_g_err[i].type == TOKEN_FACTOR_DIV)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_FACTOR_DIV");
|
||||
else if (tokens_g_err[i].type == TOKEN_EQUAL)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_EQUAL");
|
||||
else if (tokens_g_err[i].type == TOKEN_END)
|
||||
ft_dprintf(STDERR_FILENO, "%22s", "TOKEN_END");
|
||||
ft_dprintf(STDERR_FILENO, "token[%2i] - type : %22s", i, token_type_to_str(tokens_g_err[i].type));
|
||||
|
||||
ft_putstr(" - value : ");
|
||||
|
||||
if (tokens_g_err[i].type == TOKEN_NUMBER_INT)
|
||||
{
|
||||
ft_dprintf(STDERR_FILENO, "%i\n", tokens_g_err[i].value_int);
|
||||
@@ -71,29 +47,9 @@ static void print_context_terms()
|
||||
while (terms_g_err[i].position != TERM_END)
|
||||
{
|
||||
ft_dprintf(STDERR_FILENO, "term[%2i] - ", i);
|
||||
|
||||
// position
|
||||
ft_dprintf(STDERR_FILENO, "%8s : ", "position");
|
||||
if (terms_g_err[i].position == TERM_LEFT)
|
||||
ft_dprintf(STDERR_FILENO, "%10s", "TERM_LEFT");
|
||||
else if (terms_g_err[i].position == TERM_RIGHT)
|
||||
ft_dprintf(STDERR_FILENO, "%10s", "TERM_RIGHT");
|
||||
else
|
||||
ft_dprintf(STDERR_FILENO, "%10s", "");
|
||||
|
||||
// sign
|
||||
ft_dprintf(STDERR_FILENO, " | %4s : ", "sign");
|
||||
if (terms_g_err[i].sign == TERM_PLUS)
|
||||
ft_dprintf(STDERR_FILENO, "%10s", "TERM_PLUS");
|
||||
else if (terms_g_err[i].sign == TERM_MINUS)
|
||||
ft_dprintf(STDERR_FILENO, "%10s", "TERM_MINUS");
|
||||
else
|
||||
ft_dprintf(STDERR_FILENO, "%10s", "");
|
||||
|
||||
// coefficient
|
||||
ft_dprintf(STDERR_FILENO, "%8s : %10s", "position", term_position_to_str(terms_g_err[i].position));
|
||||
ft_dprintf(STDERR_FILENO, " | %4s : %10s", "sign", term_sign_to_str(terms_g_err[i].sign));
|
||||
dprintf(STDERR_FILENO, " | %10s : %13g", "coefficient", terms_g_err[i].coefficient);
|
||||
|
||||
// exponent
|
||||
ft_dprintf(STDERR_FILENO, " | %8s : %d\n", "exponent", terms_g_err[i].exponent);
|
||||
i++;
|
||||
}
|
||||
@@ -110,6 +66,25 @@ static void print_context_polynom()
|
||||
dprintf(STDERR_FILENO, "polynom[%i]: %10g\n", i, polynom_g_err[i]);
|
||||
i++;
|
||||
}
|
||||
ft_putchar_fd('\n', STDERR_FILENO);
|
||||
}
|
||||
|
||||
static void print_context_solution()
|
||||
{
|
||||
dprintf(STDERR_FILENO, "delta_sign : %25s\n", delta_sign_to_str(solution_g_err->delta_sign));
|
||||
dprintf(STDERR_FILENO, "delta_absolute : %25g\n", solution_g_err->delta_absolute);
|
||||
// dprintf(STDERR_FILENO, "first_term_pgcd : %25g\n", solution_g_err->first_term_pgcd);
|
||||
// dprintf(STDERR_FILENO, "first_term_numerator : %25g\n", solution_g_err->first_term_numerator);
|
||||
// dprintf(STDERR_FILENO, "first_term_denominator : %25g\n", solution_g_err->first_term_denominator);
|
||||
// dprintf(STDERR_FILENO, "first_term : %25g\n", solution_g_err->first_term);
|
||||
// dprintf(STDERR_FILENO, "second_term_pgcd : %25g\n", solution_g_err->second_term_pgcd);
|
||||
// dprintf(STDERR_FILENO, "second_term_numerator : %25g\n", solution_g_err->second_term_numerator);
|
||||
// dprintf(STDERR_FILENO, "second_term_denominator: %25g\n", solution_g_err->second_term_denominator);
|
||||
// dprintf(STDERR_FILENO, "second_term : %25g\n", solution_g_err->second_term);
|
||||
// dprintf(STDERR_FILENO, "solution1 : %25g\n", solution_g_err->solution1);
|
||||
// dprintf(STDERR_FILENO, "solution2 : %25g\n", solution_g_err->solution2);
|
||||
|
||||
ft_putchar_fd('\n', STDERR_FILENO);
|
||||
}
|
||||
|
||||
void print_state()
|
||||
@@ -125,6 +100,8 @@ void print_state()
|
||||
print_context_terms();
|
||||
if (polynom_g_err)
|
||||
print_context_polynom();
|
||||
if (solution_g_err)
|
||||
print_context_solution();
|
||||
}
|
||||
|
||||
void stop_errors(const char *description, ...)
|
||||
|
||||
@@ -11,6 +11,7 @@ const char *token_type_to_str(e_token_type enum_value)
|
||||
[TOKEN_VARIABLE] = "TOKEN_VARIABLE",
|
||||
[TOKEN_NUMBER_INT] = "TOKEN_NUMBER_INT",
|
||||
[TOKEN_NUMBER_DOUBLE] = "TOKEN_NUMBER_DOUBLE",
|
||||
[TOKEN_NUMBER_INT_SUPER] = "TOKEN_NUMBER_INT_SUPER",
|
||||
[TOKEN_POWER] = "TOKEN_POWER",
|
||||
[TOKEN_SIGN_PLUS] = "TOKEN_SIGN_PLUS",
|
||||
[TOKEN_SIGN_MINUS] = "TOKEN_SIGN_MINUS",
|
||||
@@ -56,4 +57,16 @@ const char *term_sign_to_str(e_term_sign enum_value)
|
||||
[TERM_MINUS] = "TERM_MINUS",
|
||||
[TERM_NULL] = "TERM_NULL"};
|
||||
return term_sign_str[enum_value];
|
||||
}
|
||||
|
||||
const char *delta_sign_to_str(e_delta_sign enum_value)
|
||||
{
|
||||
if (enum_value > DELTA_ZERO || enum_value < DELTA_PLUS)
|
||||
return "invalid enum value";
|
||||
|
||||
static const char *const delta_sign_str[DELTA_ZERO + 1] = {
|
||||
[DELTA_PLUS] = "DELTA_PLUS",
|
||||
[DELTA_MINUS] = "DELTA_MINUS",
|
||||
[DELTA_ZERO] = "DELTA_ZERO"};
|
||||
return delta_sign_str[enum_value];
|
||||
}
|
||||
@@ -10,7 +10,7 @@ void print_debug(const char *description, ...)
|
||||
// print the formatted description
|
||||
va_list args;
|
||||
va_start(args, description);
|
||||
// ft_vdprintf(STDOUT_FILENO, description, args);
|
||||
// ft_vdprintf(STDOUT_FILENO, description, args); // it's not handling floats for the moment
|
||||
vdprintf(STDOUT_FILENO, description, args);
|
||||
va_end(args);
|
||||
}
|
||||
Reference in New Issue
Block a user