1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

Merge pull request #1550 from nbraud/factor/rhofactor

factor::rho: Refactor for readability and fewer allocations
This commit is contained in:
Alex Lyon 2020-06-20 06:17:33 -07:00 committed by GitHub
commit c97c98bd2b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 17 deletions

View file

@ -32,10 +32,17 @@ struct Factors {
} }
impl Factors { impl Factors {
fn new() -> Factors { fn one() -> Factors {
Factors { f: BTreeMap::new() } Factors { f: BTreeMap::new() }
} }
fn prime(p: u64) -> Factors {
debug_assert!(miller_rabin::is_prime(p));
let mut f = Factors::one();
f.push(p);
f
}
fn add(&mut self, prime: u64, exp: u8) { fn add(&mut self, prime: u64, exp: u8) {
debug_assert!(exp > 0); debug_assert!(exp > 0);
let n = *self.f.get(&prime).unwrap_or(&0); let n = *self.f.get(&prime).unwrap_or(&0);
@ -75,7 +82,7 @@ impl fmt::Display for Factors {
} }
fn factor(mut n: u64) -> Factors { fn factor(mut n: u64) -> Factors {
let mut factors = Factors::new(); let mut factors = Factors::one();
if n < 2 { if n < 2 {
factors.push(n); factors.push(n);

View file

@ -55,29 +55,21 @@ fn _factor<A: Arithmetic>(num: u64) -> Factors {
_factor::<A>(n) _factor::<A>(n)
}; };
let mut factors = Factors::new();
if num == 1 { if num == 1 {
return factors; return Factors::one();
} }
let n = A::new(num); let n = A::new(num);
let divisor; let divisor = match miller_rabin::test::<A>(n) {
match miller_rabin::test::<A>(n) {
Prime => { Prime => {
factors.push(num); return Factors::prime(num);
return factors;
} }
Composite(d) => { Composite(d) => d,
divisor = d; Pseudoprime => find_divisor::<A>(n),
}
Pseudoprime => {
divisor = find_divisor::<A>(n);
}
}; };
factors *= _factor(divisor); let mut factors = _factor(divisor);
factors *= _factor(num / divisor); factors *= _factor(num / divisor);
factors factors
} }

View file

@ -15,7 +15,7 @@ use crate::Factors;
include!(concat!(env!("OUT_DIR"), "/prime_table.rs")); include!(concat!(env!("OUT_DIR"), "/prime_table.rs"));
pub(crate) fn factor(mut num: u64) -> (Factors, u64) { pub(crate) fn factor(mut num: u64) -> (Factors, u64) {
let mut factors = Factors::new(); let mut factors = Factors::one();
for &(prime, inv, ceil) in P_INVS_U64 { for &(prime, inv, ceil) in P_INVS_U64 {
if num == 1 { if num == 1 {
break; break;