computorv1/src/lib.rs

149 lines
3.8 KiB
Rust
Raw Normal View History

2023-08-01 14:36:58 +00:00
use std::error::Error;
use crate::parser::tokenizer::tokenize;
use crate::parser::sanitizer::sanitize_tokens;
use crate::parser::ast_builder::build_ast;
2023-08-01 14:36:58 +00:00
pub mod parser;
2023-08-01 14:36:58 +00:00
struct _Rational {
2023-08-01 14:36:58 +00:00
numerator: i128,
denominator: i128,
}
struct _GaussianRational {
real: _Rational,
imaginary: _Rational,
2023-08-01 14:36:58 +00:00
}
pub fn parse(query: &str) -> Result<Vec<f64>, Box<dyn Error>> {
let tokens = tokenize(query)?;
println!("{:?}", tokens);
2023-08-01 14:36:58 +00:00
let sanitized_tokens = sanitize_tokens(tokens)?;
println!("{:?}", sanitized_tokens);
let _ast = build_ast(sanitized_tokens);
2023-08-01 14:36:58 +00:00
Ok(vec![])
}
fn print_reduced_form(equation: &Vec<f64>) {
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<f64>) {
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<f64>) {
println!("The solution is:");
println!("{}", -1. * equation[0] / equation[1]);
}
fn solve_degree_2(equation: Vec<f64>) {
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<f64>) {
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]
2023-08-01 14:36:58 +00:00
fn parse_degree_0() {
let query = "5 * X^0 = 3 * X^0";
let result: Vec<f64> = vec![2.];
assert_eq!(parse(query).unwrap(), result);
}
#[test]
2023-08-01 14:36:58 +00:00
fn parse_degree_1() {
let query = "5 * X^0 + 3 * X^1 = 3 * X^0";
let result: Vec<f64> = vec![2., 3.];
assert_eq!(parse(query).unwrap(), result);
}
#[test]
2023-08-01 14:36:58 +00:00
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]
2023-08-01 14:36:58 +00:00
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);
}
}