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 fn pretty(v: &Vec<GaussianRational>) { | ||||
|     v[0].print(); | ||||
|     for i in 1..v.len() { | ||||
|         print!(" + "); | ||||
|         v[i].print(); | ||||
|         print!("x^{i}"); | ||||
| pub fn format(v: &Vec<GaussianRational>) -> String { | ||||
|     let mut format; | ||||
|     format = v[0].format(); | ||||
|     if v.len() > 1 { | ||||
|         if format == "" { | ||||
|             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>> { | ||||
|  |  | |||
|  | @ -16,8 +16,10 @@ fn main() { | |||
|         println!("Error during evaluation: {e}"); | ||||
|         process::exit(1); | ||||
|     }); | ||||
|     computorv1::pretty(&evaluated); | ||||
|     if is_equation { | ||||
|         println!("{} = 0", computorv1::format(&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)) | ||||
| } | ||||
| 
 | ||||
| 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
 | ||||
| fn gcd(a: i128, b: i128) -> i128 { | ||||
|     if b == 0 { | ||||
|  | @ -56,12 +83,40 @@ impl Rational { | |||
|         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
 | ||||
|     pub fn print(&self) { | ||||
|     pub fn format(&self) -> String { | ||||
|         match (self.numerator, self.denominator) { | ||||
|             (_, 1) => print!("{}", self.numerator), | ||||
|             _ => print!("{}/{}", self.numerator, self.denominator), | ||||
|         }; | ||||
|             (_, 1) => format!("{}", self.numerator), | ||||
|             _ => format!("{}", self.format_fract()), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // 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
 | ||||
|     pub fn print(&self) { | ||||
|         self.real.print(); | ||||
|         print!("+"); | ||||
|         self.imaginary.print(); | ||||
|         print!("i"); | ||||
|     pub fn format(&self) -> String { | ||||
|         match (self.real().is_zero(), self.imaginary.is_zero()) { | ||||
|             (true, true) => format!(""), | ||||
|             (true, false) => format!("{}i", self.imaginary.format()), | ||||
|             (false, true) => format!("{}", self.real.format()), | ||||
|             (false, false) => format!("{} + {}i", self.real.format(), self.imaginary.format()) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn is_real(&self) -> bool { | ||||
|  | @ -272,6 +329,24 @@ impl ops::Div<GaussianRational> for GaussianRational { | |||
| mod tests { | ||||
|     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] | ||||
|     fn gcd_test() { | ||||
|         assert_eq!(gcd(7, 3), 1); | ||||
|  | @ -343,6 +418,18 @@ mod tests { | |||
|             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] | ||||
|         fn getters() { | ||||
|             let rational = Rational::new(5, 7); | ||||
|  | @ -399,6 +486,21 @@ mod tests { | |||
|             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] | ||||
|         fn getters() { | ||||
|             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"); | ||||
|     let x = minus_one() * equation[0] / equation[1]; | ||||
|     println!("The solution is"); | ||||
|     println!("{:?}", x); | ||||
|     let mut format = x.format(); | ||||
|     if format == "" { | ||||
|         format = String::from("0"); | ||||
|     } | ||||
|     println!("x = {}", format); | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug)] | ||||
|  | @ -30,34 +34,13 @@ struct MyCompSqrt { | |||
|     sign: i128, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| fn simplify_sqrt(mut n: i128) -> (i128, i128) { | ||||
| fn simplify_sqrt(n: i128) -> (i128, i128) { | ||||
|     if n == 0 { | ||||
|         return (0, 0); | ||||
|     } | ||||
|     let mut prime_factors = vec![]; | ||||
|     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 prime_factors = get_prime_factors(n); | ||||
|     let (mut natural, mut irrational) = (1, 1); | ||||
|     prime_factors = prime_factors.into_iter().rev().collect(); | ||||
|     dbg!(&prime_factors); | ||||
|     while prime_factors.len() > 1 { | ||||
|         let pop = prime_factors.pop().unwrap(); | ||||
|         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 { | ||||
|     let numerator_irrational = n.numerator * n.denominator; | ||||
|     dbg!(numerator_irrational); | ||||
|     let (mut numerator_natural, numerator_irrational) = simplify_sqrt(numerator_irrational); | ||||
|     dbg!(numerator_natural); | ||||
|     dbg!(numerator_irrational); | ||||
| 
 | ||||
|     numerator_natural *= a.denominator; | ||||
|     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> { | ||||
|     for i in (1..equation.len()).rev() { | ||||
|         if equation[i] == zero() { | ||||
|  | @ -395,7 +374,6 @@ pub fn solve(mut equation: Vec<GaussianRational>) -> Vec<GaussianRational> { | |||
|             break; | ||||
|         } | ||||
|     } | ||||
|     crate::pretty(&equation); | ||||
|     match equation.len() { | ||||
|         0 => unreachable!(), | ||||
|         1 => degree_zero(equation), | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue