feat(*): prep 42
This commit is contained in:
		
							parent
							
								
									0f363e0452
								
							
						
					
					
						commit
						8260e7fc92
					
				
							
								
								
									
										29
									
								
								src/lib.rs
								
								
								
								
							
							
						
						
									
										29
									
								
								src/lib.rs
								
								
								
								
							|  | @ -8,14 +8,29 @@ pub mod parser; | ||||||
| pub mod maths; | pub mod maths; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| pub fn pretty(v: &Vec<GaussianRational>) { | pub fn format(v: &Vec<GaussianRational>) -> String { | ||||||
|     v[0].print(); |     let mut format; | ||||||
|     for i in 1..v.len() { |     format = v[0].format(); | ||||||
|         print!(" + "); |     if v.len() > 1 { | ||||||
|         v[i].print(); |         if format == "" { | ||||||
|         print!("x^{i}"); |             format = format!("{}x", v[1].format()); | ||||||
|  |         } else { | ||||||
|  |             format = format!("{format} + {}x", v[1].format()); | ||||||
|         } |         } | ||||||
|     println!(""); |     } | ||||||
|  |     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::<Vec<_>>().join("- "); | ||||||
|  |     format = format.split("1x").collect::<Vec<_>>().join("x"); | ||||||
|  |     format.split("1i").collect::<Vec<_>>().join("i") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn parse(query: &str) -> Result<Node, Box<dyn Error>> { | pub fn parse(query: &str) -> Result<Node, Box<dyn Error>> { | ||||||
|  |  | ||||||
|  | @ -16,8 +16,10 @@ fn main() { | ||||||
|         println!("Error during evaluation: {e}"); |         println!("Error during evaluation: {e}"); | ||||||
|         process::exit(1); |         process::exit(1); | ||||||
|     }); |     }); | ||||||
|     computorv1::pretty(&evaluated); |  | ||||||
|     if is_equation { |     if is_equation { | ||||||
|  |         println!("{} = 0", computorv1::format(&evaluated)); | ||||||
|         computorv1::maths::solver::solve(evaluated); |         computorv1::maths::solver::solve(evaluated); | ||||||
|  |     } else { | ||||||
|  |         println!("{}", computorv1::format(&evaluated)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										120
									
								
								src/maths.rs
								
								
								
								
							
							
						
						
									
										120
									
								
								src/maths.rs
								
								
								
								
							|  | @ -16,6 +16,33 @@ fn one() -> GaussianRational { | ||||||
|     GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1)) |     GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | fn get_prime_factors(mut n: i128) -> Vec<i128> { | ||||||
|  |     if n == 0 { | ||||||
|  |         return [0].to_vec(); | ||||||
|  |     } | ||||||
|  |     let mut prime_factors = vec![]; | ||||||
|  |     let mut prime = 3; | ||||||
|  |     while n != 1 && prime * prime < n + 8 { | ||||||
|  |         if n % (prime - 1) == 0 { | ||||||
|  |             prime_factors.push(prime - 1); | ||||||
|  |             n /= prime - 1; | ||||||
|  |         } else if n % (prime + 1) == 0 { | ||||||
|  |             prime_factors.push(prime + 1); | ||||||
|  |             n /= prime + 1; | ||||||
|  |         } else { | ||||||
|  |             if prime > 5 { | ||||||
|  |                 prime += 6; | ||||||
|  |             } else { | ||||||
|  |                 prime += 1; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     if n != 1 { | ||||||
|  |         prime_factors.push(n); | ||||||
|  |     } | ||||||
|  |     prime_factors | ||||||
|  | } | ||||||
|  | 
 | ||||||
| //TODO slow ? check Stein's algorithm (binaryGCD) + tests
 | //TODO slow ? check Stein's algorithm (binaryGCD) + tests
 | ||||||
| fn gcd(a: i128, b: i128) -> i128 { | fn gcd(a: i128, b: i128) -> i128 { | ||||||
|     if b == 0 { |     if b == 0 { | ||||||
|  | @ -56,12 +83,40 @@ impl Rational { | ||||||
|         Rational::new(self.numerator, self.denominator * 10) |         Rational::new(self.numerator, self.denominator * 10) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     fn format_fract(&self) -> String { | ||||||
|  |         let mut copy = self.clone(); | ||||||
|  |         let factors = get_prime_factors(self.denominator); | ||||||
|  |         dbg!(&factors); | ||||||
|  |         let mut two_count = 0; | ||||||
|  |         let mut five_count = 0; | ||||||
|  |         for factor in factors { | ||||||
|  |             if factor == 2 { | ||||||
|  |                 two_count += 1; | ||||||
|  |             } else if factor == 5 { | ||||||
|  |                 five_count += 1; | ||||||
|  |             } else { | ||||||
|  |                 return format!("{}/{}", self.numerator, self.denominator); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         while two_count < five_count { | ||||||
|  |             copy.numerator *= 2; | ||||||
|  |             copy.denominator *= 2; | ||||||
|  |             two_count += 1; | ||||||
|  |         } | ||||||
|  |         while five_count < two_count { | ||||||
|  |             copy.numerator *= 5; | ||||||
|  |             copy.denominator *= 5; | ||||||
|  |             five_count += 1; | ||||||
|  |         } | ||||||
|  |         format!("{}.{}", copy.numerator / copy.denominator, copy.numerator % copy.denominator) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // TODO return string
 |     // TODO return string
 | ||||||
|     pub fn print(&self) { |     pub fn format(&self) -> String { | ||||||
|         match (self.numerator, self.denominator) { |         match (self.numerator, self.denominator) { | ||||||
|             (_, 1) => print!("{}", self.numerator), |             (_, 1) => format!("{}", self.numerator), | ||||||
|             _ => print!("{}/{}", self.numerator, self.denominator), |             _ => format!("{}", self.format_fract()), | ||||||
|         }; |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO rename or move to better scope, only used in complex div ?
 |     // TODO rename or move to better scope, only used in complex div ?
 | ||||||
|  | @ -199,11 +254,13 @@ impl GaussianRational { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // TODO return string, avoid printing real or imag part if zero
 |     // TODO return string, avoid printing real or imag part if zero
 | ||||||
|     pub fn print(&self) { |     pub fn format(&self) -> String { | ||||||
|         self.real.print(); |         match (self.real().is_zero(), self.imaginary.is_zero()) { | ||||||
|         print!("+"); |             (true, true) => format!(""), | ||||||
|         self.imaginary.print(); |             (true, false) => format!("{}i", self.imaginary.format()), | ||||||
|         print!("i"); |             (false, true) => format!("{}", self.real.format()), | ||||||
|  |             (false, false) => format!("{} + {}i", self.real.format(), self.imaginary.format()) | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn is_real(&self) -> bool { |     pub fn is_real(&self) -> bool { | ||||||
|  | @ -272,6 +329,24 @@ impl ops::Div<GaussianRational> for GaussianRational { | ||||||
| mod tests { | mod tests { | ||||||
|     use super::*; |     use super::*; | ||||||
|     
 |     
 | ||||||
|  |     #[test] | ||||||
|  |     fn constant_generators() { | ||||||
|  |         assert_eq!(zero(), GaussianRational::new(Rational::new(0, 1), Rational::new(0, 1))); | ||||||
|  |         assert_eq!(minus_one(), GaussianRational::new(Rational::new(-1, 1), Rational::new(0, 1))); | ||||||
|  |         assert_eq!(one(), GaussianRational::new(Rational::new(1, 1), Rational::new(0, 1))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn get_prime_factors_test() { | ||||||
|  |         assert_eq!(get_prime_factors(5), vec![5]); | ||||||
|  |         assert_eq!(get_prime_factors(8), vec![2, 2, 2]); | ||||||
|  |         assert_eq!(get_prime_factors(4), vec![2, 2]); | ||||||
|  |         assert_eq!(get_prime_factors(9), vec![3, 3]); | ||||||
|  |         assert_eq!(get_prime_factors(10), vec![2, 5]); | ||||||
|  |         assert_eq!(get_prime_factors(18), vec![2, 3, 3]); | ||||||
|  |         assert_eq!(get_prime_factors(16), vec![2, 2, 2, 2]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     #[test] |     #[test] | ||||||
|     fn gcd_test() { |     fn gcd_test() { | ||||||
|         assert_eq!(gcd(7, 3), 1); |         assert_eq!(gcd(7, 3), 1); | ||||||
|  | @ -343,6 +418,18 @@ mod tests { | ||||||
|             assert_eq!(rational.is_zero(), false); |             assert_eq!(rational.is_zero(), false); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         #[test] | ||||||
|  |         fn format() { | ||||||
|  |             let whole = Rational::new(5, 1); | ||||||
|  |             let rational = Rational::new(5, 3); | ||||||
|  |             let floating = Rational::new(5, 4); | ||||||
|  |             assert_eq!(whole.format(), String::from("5")); | ||||||
|  |             assert_eq!(rational.format(), String::from("5/3")); | ||||||
|  |             assert_eq!(floating.format(), String::from("1.25")); | ||||||
|  |             let floating = Rational::new(37, 25); | ||||||
|  |             assert_eq!(floating.format(), String::from("1.48")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         #[test] |         #[test] | ||||||
|         fn getters() { |         fn getters() { | ||||||
|             let rational = Rational::new(5, 7); |             let rational = Rational::new(5, 7); | ||||||
|  | @ -399,6 +486,21 @@ mod tests { | ||||||
|             assert_eq!(gaussian_rational.is_real(), true); |             assert_eq!(gaussian_rational.is_real(), true); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         #[test] | ||||||
|  |         fn format() { | ||||||
|  |             let whole = Rational::new(5, 1); | ||||||
|  |             let rational = Rational::new(5, 3); | ||||||
|  |             let zero = Rational::new(0, 1); | ||||||
|  |             let a = GaussianRational::new(zero, zero); | ||||||
|  |             let b = GaussianRational::new(zero, rational); | ||||||
|  |             let c = GaussianRational::new(whole, zero); | ||||||
|  |             let d = GaussianRational::new(whole, rational); | ||||||
|  |             assert_eq!(a.format(), String::from("")); | ||||||
|  |             assert_eq!(b.format(), String::from("5/3i")); | ||||||
|  |             assert_eq!(c.format(), String::from("5")); | ||||||
|  |             assert_eq!(d.format(), String::from("5 + 5/3i")); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         #[test] |         #[test] | ||||||
|         fn getters() { |         fn getters() { | ||||||
|             let gaussian_rational = GaussianRational::new(Rational::new(5, 7), Rational::new(8, 3)); |             let gaussian_rational = GaussianRational::new(Rational::new(5, 7), Rational::new(8, 3)); | ||||||
|  |  | ||||||
|  | @ -13,7 +13,11 @@ fn degree_one(equation: Vec<GaussianRational>) { | ||||||
|     println!("Polynomial degree: 1"); |     println!("Polynomial degree: 1"); | ||||||
|     let x = minus_one() * equation[0] / equation[1]; |     let x = minus_one() * equation[0] / equation[1]; | ||||||
|     println!("The solution is"); |     println!("The solution is"); | ||||||
|     println!("{:?}", x); |     let mut format = x.format(); | ||||||
|  |     if format == "" { | ||||||
|  |         format = String::from("0"); | ||||||
|  |     } | ||||||
|  |     println!("x = {}", format); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
|  | @ -30,34 +34,13 @@ struct MyCompSqrt { | ||||||
|     sign: i128, |     sign: i128, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | fn simplify_sqrt(n: i128) -> (i128, i128) { | ||||||
| fn simplify_sqrt(mut n: i128) -> (i128, i128) { |  | ||||||
|     if n == 0 { |     if n == 0 { | ||||||
|         return (0, 0); |         return (0, 0); | ||||||
|     } |     } | ||||||
|     let mut prime_factors = vec![]; |     let mut prime_factors = get_prime_factors(n); | ||||||
|     let mut prime = 3; |  | ||||||
|     while n != 1 && prime * prime < n { |  | ||||||
|         if n % (prime - 1) == 0 { |  | ||||||
|             prime_factors.push(prime - 1); |  | ||||||
|             n /= prime - 1; |  | ||||||
|         } else if n % (prime + 1) == 0 { |  | ||||||
|             prime_factors.push(prime + 1); |  | ||||||
|             n /= prime + 1; |  | ||||||
|         } else { |  | ||||||
|             if prime > 5 { |  | ||||||
|                 prime += 6; |  | ||||||
|             } else { |  | ||||||
|                 prime += 1; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     if n != 1 { |  | ||||||
|         prime_factors.push(n); |  | ||||||
|     } |  | ||||||
|     let (mut natural, mut irrational) = (1, 1); |     let (mut natural, mut irrational) = (1, 1); | ||||||
|     prime_factors = prime_factors.into_iter().rev().collect(); |     prime_factors = prime_factors.into_iter().rev().collect(); | ||||||
|     dbg!(&prime_factors); |  | ||||||
|     while prime_factors.len() > 1 { |     while prime_factors.len() > 1 { | ||||||
|         let pop = prime_factors.pop().unwrap(); |         let pop = prime_factors.pop().unwrap(); | ||||||
|         if *prime_factors.last().unwrap() == pop { |         if *prime_factors.last().unwrap() == pop { | ||||||
|  | @ -265,10 +248,7 @@ fn degree_two_complex(a: GaussianRational, b: GaussianRational, c: GaussianRatio | ||||||
| 
 | 
 | ||||||
| fn sqrt(n: Rational, a: Rational) -> MySqrt { | fn sqrt(n: Rational, a: Rational) -> MySqrt { | ||||||
|     let numerator_irrational = n.numerator * n.denominator; |     let numerator_irrational = n.numerator * n.denominator; | ||||||
|     dbg!(numerator_irrational); |  | ||||||
|     let (mut numerator_natural, numerator_irrational) = simplify_sqrt(numerator_irrational); |     let (mut numerator_natural, numerator_irrational) = simplify_sqrt(numerator_irrational); | ||||||
|     dbg!(numerator_natural); |  | ||||||
|     dbg!(numerator_irrational); |  | ||||||
| 
 | 
 | ||||||
|     numerator_natural *= a.denominator; |     numerator_natural *= a.denominator; | ||||||
|     let mut denominator = n.denominator * 2 * a.numerator; |     let mut denominator = n.denominator * 2 * a.numerator; | ||||||
|  | @ -386,7 +366,6 @@ fn degree_two(equation: Vec<GaussianRational>) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| pub fn solve(mut equation: Vec<GaussianRational>) -> Vec<GaussianRational> { | pub fn solve(mut equation: Vec<GaussianRational>) -> Vec<GaussianRational> { | ||||||
|     for i in (1..equation.len()).rev() { |     for i in (1..equation.len()).rev() { | ||||||
|         if equation[i] == zero() { |         if equation[i] == zero() { | ||||||
|  | @ -395,7 +374,6 @@ pub fn solve(mut equation: Vec<GaussianRational>) -> Vec<GaussianRational> { | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     crate::pretty(&equation); |  | ||||||
|     match equation.len() { |     match equation.len() { | ||||||
|         0 => unreachable!(), |         0 => unreachable!(), | ||||||
|         1 => degree_zero(equation), |         1 => degree_zero(equation), | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue