use std::error::Error; use crate::parser::tokenizer::tokenize; use crate::parser::sanitizer::sanitize_tokens; use crate::parser::ast_builder::build_ast; pub mod parser; struct _Rational { numerator: i128, denominator: i128, } struct _GaussianRational { real: _Rational, imaginary: _Rational, } pub fn parse(query: &str) -> Result, Box> { let tokens = tokenize(query)?; println!("{:?}", tokens); let sanitized_tokens = sanitize_tokens(tokens)?; println!("{:?}", sanitized_tokens); let _ast = build_ast(sanitized_tokens); Ok(vec![]) } 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}"); //(-b +- sqrt(delta)) / 2a } 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"); //(-b +- i sqrt(-delta)) / 2a } else { let x = -equation[1] / (2. * equation[2]); println!("Discriminant is zero, the solution is:"); println!("{x}"); //-b / 2a } } 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!(), } } #[cfg(test)] mod tests { use super::*; #[test] fn parse_degree_0() { let query = "5 * X^0 = 3 * X^0"; let result: Vec = vec![2.]; assert_eq!(parse(query).unwrap(), result); } #[test] fn parse_degree_1() { let query = "5 * X^0 + 3 * X^1 = 3 * X^0"; let result: Vec = vec![2., 3.]; assert_eq!(parse(query).unwrap(), result); } #[test] fn parse_degree_2() { let query = "5 * X^0 + 6 * X^1 + 8 * X^2 = 3 * X^0 - 2 * X^2"; let result = vec![2., 6., 10.]; assert_eq!(parse(query).unwrap(), result); } #[test] fn parse_random_order() { let query = "9.3 * X^3 + 4.3 * X^0 + 3.4 * X^2 - 1.5 * X^3 - 13.12 * X^1 = 1.4 * X^2 - 5.1 * X^3 + 1.4 * X^1 -6.3 * X^0"; let result = vec![10.6, -14.52, 2., 12.9]; assert_eq!(parse(query).unwrap(), result); } }