use std::error::Error; use crate::parser::tokenizer::tokenize; use crate::parser::sanitizer::sanitize_tokens; use crate::parser::ast_builder::{build_ast, Node}; use crate::maths::GaussianRational; pub mod parser; pub mod maths; pub fn format(v: &Vec) -> String { let mut format; format = v[0].format(); if v.len() > 1 { if format == "" { format = format!("{}x", v[1].format()); } else { format = format!("{format} + {}x", v[1].format()); } } for i in 2..v.len() { let tmp = v[i].format(); if tmp != "" { if format == ""{ format = format!("{tmp}x^{i}"); } else { format = format!("{format} + {}x^{i}", tmp); } } } format = format.split("+ -").collect::>().join("- "); format = format.split("1x").collect::>().join("x"); format.split("1i").collect::>().join("i") } pub fn parse(query: &str) -> Result> { let tokens = tokenize(query)?; let sanitized_tokens = sanitize_tokens(tokens)?; let ast = build_ast(sanitized_tokens); Ok(ast) } fn print_reduced_form(equation: &Vec) { let mut string = String::from("Reduced form: "); for (i, n) in equation.iter().enumerate() { let mut n = *n; if n < 0. { string += " - "; n *= -1.; } else if i != 0 { string += " + "; } string.push_str(&n.to_string()); string.push_str(" * X^"); string.push_str(&i.to_string()); } string += " = 0"; println!("{string}"); } fn sqrt(n: f64) -> f64 { let mut z = 1.; for _ in 0..10 { z -= (z * z - n) / (2. * z); } z } fn solve_degree_0(equation: Vec) { if equation[0] == 0. { println!("Each real number is a solution."); } else { println!("There are no solutions to this equation"); } } fn solve_degree_1(equation: Vec) { println!("The solution is:"); println!("{}", -1. * equation[0] / equation[1]); } fn solve_degree_2(equation: Vec) { let delta = equation[1] * equation[1] - 4. * equation[2] * equation[0]; if delta > 0. { let sqrt_delta = sqrt(delta); let x1 = (-equation[1] - sqrt_delta) / (2. * equation[2]); let x2 = (-equation[1] + sqrt_delta) / (2. * equation[2]); println!("Discriminant is strictly positive, the two solutions are:"); println!("{x1}"); println!("{x2}"); } else if delta < 0. { let sqrt_delta = sqrt(delta); let a = -equation[1] / (2. * equation[2]); let b = sqrt_delta / (2. * equation[2]); println!("Discriminant is strictly negative, the two complex solutions are:"); println!("{a} + {b}i"); println!("{a} - {b}i"); } else { let x = -equation[1] / (2. * equation[2]); println!("Discriminant is zero, the solution is:"); println!("{x}"); } } pub fn solve(equation: Vec) { let degree = equation.len() - 1; print_reduced_form(&equation); println!("Polynomial degree: {degree}"); match degree { 0 => solve_degree_0(equation), 1 => solve_degree_1(equation), 2 => solve_degree_2(equation), _ if degree > 2 => println!("The polynomial degree is strictly greater than 2, I can't solve."), _ => unreachable!(), } }