diff --git a/Makefile b/Makefile index 6afad06..f58d400 100644 --- a/Makefile +++ b/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: diff --git a/README.md b/README.md index bcd2aa0..dc6b33b 100644 --- a/README.md +++ b/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 \ No newline at end of file + -> 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 diff --git a/headers/computorv1.h b/headers/computorv1.h index ee26856..1838e5d 100644 --- a/headers/computorv1.h +++ b/headers/computorv1.h @@ -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 \ No newline at end of file diff --git a/src/launcher.c b/src/launcher.c index f8073b3..ed68088 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -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(); diff --git a/src/lexer.c b/src/lexer.c index 977dd66..f3ddd67 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -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; } diff --git a/src/main.c b/src/main.c index aebc1e3..82f9f3a 100644 --- a/src/main.c +++ b/src/main.c @@ -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(); } } diff --git a/src/parser.c b/src/parser.c index a89e1b7..f7597b9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -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; } \ No newline at end of file diff --git a/src/solver.c b/src/solver.c new file mode 100644 index 0000000..0b07984 --- /dev/null +++ b/src/solver.c @@ -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; + // } +} diff --git a/src/utils/errors.c b/src/utils/errors.c index 66e1e85..c291720 100644 --- a/src/utils/errors.c +++ b/src/utils/errors.c @@ -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, ...) diff --git a/src/utils/print_enums.c b/src/utils/print_enums.c index 2abd71a..b48afa1 100644 --- a/src/utils/print_enums.c +++ b/src/utils/print_enums.c @@ -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]; } \ No newline at end of file diff --git a/src/utils/printer.c b/src/utils/printer.c index f6f8b98..4867341 100644 --- a/src/utils/printer.c +++ b/src/utils/printer.c @@ -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); } \ No newline at end of file