diff --git a/src/algorithms/pollards_rho.rs b/src/algorithms/pollards_rho.rs index 5e69588..2280766 100644 --- a/src/algorithms/pollards_rho.rs +++ b/src/algorithms/pollards_rho.rs @@ -1,28 +1,29 @@ mod utils; +use std::marker::PhantomData; + use crate::primality_test; use crate::traits::PrimalityTest; -use crate::Factorize; +use crate::PrimeFactorization; pub struct PollardsRho; -type PrimeTester = Box; -impl Factorize for PollardsRho { - fn factorize(&self, n: u128) -> Vec { - RecursivePollardsRho::new(n, Box::new(primality_test::MillerRabin)) +impl PrimeFactorization for PollardsRho { + fn prime_factorization(n: u128) -> Vec { + RecursivePollardsRho::::new(n) .solve() .factors } } -struct RecursivePollardsRho { +struct RecursivePollardsRho { n: u128, factors: Vec, - prime_tester: PrimeTester, + prime_tester: PhantomData

, } -impl RecursivePollardsRho { - fn new(mut n: u128, prime_tester: PrimeTester) -> Self { +impl RecursivePollardsRho

{ + fn new(mut n: u128) -> Self { let mut factors = vec![]; while n % 2 == 0 { factors.push(2); @@ -31,7 +32,7 @@ impl RecursivePollardsRho { Self { n, factors, - prime_tester, + prime_tester: PhantomData, } } @@ -59,7 +60,7 @@ impl RecursivePollardsRho { fn get_divisor_with_pollards_rho(&self, n: u128) -> DivisorOfN { let d = pollards_rho(n); - if self.prime_tester.is_prime(d) { + if P::is_prime(d) { return DivisorOfN::Prime(d); } if d == 1 || d == n { @@ -91,7 +92,7 @@ mod tests { fn composites() { let test_cases = [(8051, vec![83, 97]), (15, vec![3, 5]), (4096, vec![2; 12])]; for (n, expected) in test_cases { - let mut actual = PollardsRho.factorize(n); + let mut actual = PollardsRho::prime_factorization(n); actual.sort_unstable(); assert_eq!(actual, expected); } @@ -101,7 +102,7 @@ mod tests { fn primes() { let primes = [3, 5, 19, 29, 37, 7027, 13037]; for p in primes { - let actual = PollardsRho.factorize(p); + let actual = PollardsRho::prime_factorization(p); assert_eq!(actual, vec![p]); } } diff --git a/src/algorithms/trial_division.rs b/src/algorithms/trial_division.rs index 699ea99..ded7401 100644 --- a/src/algorithms/trial_division.rs +++ b/src/algorithms/trial_division.rs @@ -1,9 +1,9 @@ -use crate::Factorize; +use crate::PrimeFactorization; pub struct TrialDivision; -impl Factorize for TrialDivision { - fn factorize(&self, n: u128) -> Vec { +impl PrimeFactorization for TrialDivision { + fn prime_factorization(n: u128) -> Vec { if n <= 1 { return vec![n]; } @@ -62,11 +62,11 @@ mod tests { #[test] fn factorize_prime() { - assert_eq!(TrialDivision.factorize(13), vec![13]); + assert_eq!(TrialDivision::prime_factorization(13), vec![13]); } #[test] fn factorize_composite() { - assert_eq!(TrialDivision.factorize(12), vec![2, 2, 3]); + assert_eq!(TrialDivision::prime_factorization(12), vec![2, 2, 3]); } } diff --git a/src/factorization.rs b/src/factorization.rs index 088b195..63c881b 100644 --- a/src/factorization.rs +++ b/src/factorization.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use std::fmt; -use crate::Factorize; +use crate::PrimeFactorization; static SUPERSCRIPTS: [&str; 10] = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]; @@ -11,10 +11,10 @@ pub struct Factorization { } impl Factorization { - pub fn new(n: u128, f: impl Factorize) -> Self { + pub fn new(n: u128) -> Self { Factorization { number: n, - factors: f.factorize(n), + factors: F::prime_factorization(n), } } diff --git a/src/lib.rs b/src/lib.rs index 3043fa4..44200fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,4 +4,4 @@ pub mod traits; pub mod primality_test; pub use factorization::Factorization; -pub use traits::Factorize; +pub use traits::PrimeFactorization; diff --git a/src/main.rs b/src/main.rs index aab53e4..70fd99a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,8 @@ fn main() { .parse() .expect("Please provide a valid positive integer"); match method.as_str() { - "pollards_rho" => println!("{}", Factorization::new(n, algorithms::PollardsRho)), - "trial_division" => println!("{}", Factorization::new(n, algorithms::TrialDivision)), + "pollards_rho" => println!("{}", Factorization::new::(n)), + "trial_division" => println!("{}", Factorization::new::(n)), _ => eprintln!("Unknown algorithm. Available options: pollards_rho, trial_division"), } } diff --git a/src/primality_test/miller_rabin.rs b/src/primality_test/miller_rabin.rs index 71741f8..4d7e70a 100644 --- a/src/primality_test/miller_rabin.rs +++ b/src/primality_test/miller_rabin.rs @@ -1,13 +1,13 @@ mod composite_evidence; mod utils; -use crate::traits::PrimalityTest; use self::composite_evidence::CompositeEvidence; +use crate::traits::PrimalityTest; pub struct MillerRabin; impl PrimalityTest for MillerRabin { - fn is_prime(&self, p: u128) -> bool { + fn is_prime(p: u128) -> bool { if p == 2 || p == 3 { return true; } @@ -21,7 +21,7 @@ impl PrimalityTest for MillerRabin { fn miller_rabin(p: u128, trials: usize) -> bool { let evidence = CompositeEvidence::new(p); let likely_prime = |witness| !evidence.witnessed_by(witness); - utils::RandomIntegers::new(2..p-1) + utils::RandomIntegers::new(2..p - 1) .take(trials) .all(likely_prime) } @@ -43,7 +43,7 @@ mod tests { 2u128.pow(61) - 1, ]; for prime in primes { - assert!(MillerRabin.is_prime(prime), "Failed on prime {prime}"); + assert!(MillerRabin::is_prime(prime), "Failed on prime {prime}"); } } @@ -51,7 +51,7 @@ mod tests { fn test_composite_numbers() { for composite in [4, 15, 35, 49, 1001] { assert!( - !MillerRabin.is_prime(composite), + !MillerRabin::is_prime(composite), "Failed on composite {composite}" ); } @@ -66,7 +66,7 @@ mod tests { ]; for carmichael in carmichaels { assert!( - !MillerRabin.is_prime(carmichael), + !MillerRabin::is_prime(carmichael), "Failed on Carmichael number {carmichael}" ); } diff --git a/src/traits.rs b/src/traits.rs index 2e66bf8..c9c8157 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -1,7 +1,7 @@ -pub trait Factorize { - fn factorize(&self, n: u128) -> Vec; +pub trait PrimeFactorization { + fn prime_factorization(n: u128) -> Vec; } pub trait PrimalityTest { - fn is_prime(&self, p: u128) -> bool; + fn is_prime(p: u128) -> bool; }