feat(maths): creation + clean maths in parser
This commit is contained in:
parent
b1eb997703
commit
8e3ebcd2a5
16
src/lib.rs
16
src/lib.rs
|
@ -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::*;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 zero() -> GaussianRational {
|
||||
GaussianRational {
|
||||
real: Rational {
|
||||
numerator: 0,
|
||||
denominator: 1,
|
||||
},
|
||||
imaginary: Rational {
|
||||
numerator: 0,
|
||||
denominator: 1,
|
||||
}
|
||||
}
|
||||
fn rational_zero() -> Rational {
|
||||
Rational::new(0, 1)
|
||||
}
|
||||
|
||||
fn minus_one() -> GaussianRational {
|
||||
GaussianRational {
|
||||
real: Rational {
|
||||
numerator: -1,
|
||||
denominator: 1,
|
||||
},
|
||||
imaginary: Rational {
|
||||
numerator: 0,
|
||||
denominator: 1,
|
||||
}
|
||||
}
|
||||
fn rational_one() -> Rational {
|
||||
Rational::new(1, 1)
|
||||
}
|
||||
|
||||
fn rational_minus_one() -> Rational {
|
||||
Rational::new(-1, 1)
|
||||
}
|
||||
|
||||
|
||||
fn zero() -> GaussianRational {
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue