feat(maths): creation + clean maths in parser

This commit is contained in:
gbrochar 2023-08-03 08:21:21 +02:00
parent b1eb997703
commit 8e3ebcd2a5
3 changed files with 129 additions and 103 deletions

View File

@ -4,16 +4,7 @@ use crate::parser::sanitizer::sanitize_tokens;
use crate::parser::ast_builder::{build_ast, Node};
pub mod parser;
struct _Rational {
numerator: i128,
denominator: i128,
}
struct _GaussianRational {
real: _Rational,
imaginary: _Rational,
}
pub mod maths;
pub fn parse(query: &str) -> Result<Node, Box<dyn Error>> {
let tokens = tokenize(query)?;
@ -109,8 +100,3 @@ pub fn solve(equation: Vec<f64>) {
_ => unreachable!(),
}
}
#[cfg(test)]
mod tests {
use super::*;
}

101
src/maths.rs Normal file
View File

@ -0,0 +1,101 @@
use std::ops;
//TODO slow ? check Stein's algorithm (binaryGCD)
fn gcd(a: i128, b: i128) -> i128 {
if b == 0 {
a
} else {
gcd(b, a % b)
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Rational {
numerator: i128,
denominator: i128,
}
impl Rational {
pub fn new(numerator: i128, denominator: i128) -> Self {
Self {
numerator,
denominator,
}
}
pub fn reduce(&self) -> Self {
let gcd = gcd(self.numerator, self.denominator);
Rational::new(self.numerator / gcd, self.denominator / gcd)
}
}
impl ops::Add<Rational> for Rational {
type Output = Rational;
fn add(self, rhs: Rational) -> Rational {
Rational::new(self.numerator * rhs.denominator + rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce()
}
}
impl ops::Add<i128> for Rational {
type Output = Rational;
fn add(self, rhs: i128) -> Rational {
Rational::new(self.numerator + rhs * self.denominator, self.denominator).reduce()
}
}
impl ops::Add<Rational> for i128 {
type Output = Rational;
fn add(self, rhs: Rational) -> Rational {
Rational::new(self * rhs.denominator + rhs.numerator, rhs.denominator).reduce()
}
}
impl ops::Sub<Rational> for Rational {
type Output = Rational;
fn sub(self, rhs: Rational) -> Rational {
Rational::new(self.numerator * rhs.denominator - rhs.numerator * self.denominator, self.denominator * rhs.denominator).reduce()
}
}
impl ops::Mul<Rational> for Rational {
type Output = Rational;
fn mul(self, rhs: Rational) -> Rational {
Rational::new(self.numerator * rhs.numerator, self.denominator * rhs.denominator).reduce()
}
}
impl ops::Mul<i128> for Rational {
type Output = Rational;
fn mul(self, rhs: i128) -> Rational {
Rational::new(self.numerator * rhs, self.denominator).reduce()
}
}
impl ops::Mul<Rational> for i128 {
type Output = Rational;
fn mul(self, rhs: Rational) -> Rational {
Rational::new(self * rhs.numerator, rhs.denominator).reduce()
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct GaussianRational {
real: Rational,
imaginary: Rational,
}
impl GaussianRational {
pub fn new(real: Rational, imaginary: Rational) -> Self {
Self {
real,
imaginary,
}
}
}

View File

@ -1,17 +1,5 @@
use super::Token;
#[derive(Debug, PartialEq, Clone)]
pub struct Rational {
numerator: i128,
denominator: i128,
}
#[derive(Debug, PartialEq, Clone)]
pub struct GaussianRational {
real: Rational,
imaginary: Rational,
}
use crate::maths::{GaussianRational, Rational};
#[derive(Debug, PartialEq, Clone)]
pub enum Node {
@ -23,76 +11,37 @@ pub enum Node {
}
}
/*
pub struct Node {
_lhs: Option<Box<Node>>,
_rhs: Option<Box<Node>>,
fn rational_zero() -> Rational {
Rational::new(0, 1)
}
*/
fn rational_one() -> Rational {
Rational::new(1, 1)
}
fn rational_minus_one() -> Rational {
Rational::new(-1, 1)
}
fn zero() -> GaussianRational {
GaussianRational {
real: Rational {
numerator: 0,
denominator: 1,
},
imaginary: Rational {
numerator: 0,
denominator: 1,
}
}
}
fn minus_one() -> GaussianRational {
GaussianRational {
real: Rational {
numerator: -1,
denominator: 1,
},
imaginary: Rational {
numerator: 0,
denominator: 1,
}
}
GaussianRational::new(rational_zero(), rational_zero())
}
fn one() -> GaussianRational {
GaussianRational {
real: Rational {
numerator: 1,
denominator: 1,
},
imaginary: Rational {
numerator: 0,
denominator: 1,
}
GaussianRational::new(rational_one(), rational_zero())
}
fn minus_one() -> GaussianRational {
GaussianRational::new(rational_minus_one(), rational_zero())
}
fn i() -> GaussianRational {
GaussianRational {
real: Rational {
numerator: 0,
denominator: 1,
},
imaginary: Rational {
numerator: 1,
denominator: 1,
}
}
GaussianRational::new(rational_zero(), rational_one())
}
fn minus_i() -> GaussianRational {
GaussianRational {
real: Rational {
numerator: 0,
denominator: 1,
},
imaginary: Rational {
numerator: -1,
denominator: 1,
}
}
GaussianRational::new(rational_zero(), rational_minus_one())
}
fn x() -> Vec<GaussianRational> {
@ -128,34 +77,25 @@ fn get_parentheses_map(tokens: &Vec<Token>) -> Vec<usize> {
}
fn parse_number(string: &String, sign: i128) -> GaussianRational {
let mut number = Rational {
numerator: 0,
denominator: 1,
};
let mut number = rational_zero();
let mut is_floating = false;
for c in string.chars() {
match c {
'.' => is_floating = true,
'0'..='9' => {
number.numerator = 10 * number.numerator + String::from(c).parse::<i128>().unwrap();
number = 10 * number + String::from(c).parse::<i128>().unwrap();
if is_floating == true {
number.denominator *= 10;
number = number * Rational::new(1, 10);
}
}
_ => unreachable!(),
}
}
number.numerator *= sign;
number = number * sign;
GaussianRational {
real: number,
imaginary: Rational {
numerator: 0,
denominator: 1,
}
}
GaussianRational::new(number, rational_zero())
}
fn check_parentheses(tokens: &Vec<Token>) -> bool {
@ -432,8 +372,7 @@ mod tests {
#[test]
fn two_plus_two() {
let mut two = one();
two.real.numerator = 2;
let two = GaussianRational::new(Rational::new(2, 1), rational_zero());
let tokens = vec![two_token(), plus(), two_token()];
let results = Node::Internal {