From 6713d2ad627fdc2e4e828c47bb8e5a8b55c6337b Mon Sep 17 00:00:00 2001 From: nicoo Date: Thu, 25 Jun 2020 03:38:23 +0200 Subject: [PATCH] factor: Move recursive factoring logic from rho to factor No functional change, but prepares a coming optimisation. --- src/uu/factor/src/factor.rs | 34 ++++++++++++++++++++++++++++++++-- src/uu/factor/src/rho.rs | 34 +--------------------------------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/src/uu/factor/src/factor.rs b/src/uu/factor/src/factor.rs index f825c03ab..f77792a58 100644 --- a/src/uu/factor/src/factor.rs +++ b/src/uu/factor/src/factor.rs @@ -11,6 +11,7 @@ use std::collections::BTreeMap; use std::fmt; use std::ops; +use crate::numeric::{Arithmetic, Montgomery}; use crate::{miller_rabin, rho, table}; pub struct Factors { @@ -67,6 +68,33 @@ impl fmt::Display for Factors { } } +fn _factor(num: u64) -> Factors { + use miller_rabin::Result::*; + // Shadow the name, so the recursion automatically goes from “Big” arithmetic to small. + let _factor = |n| { + // TODO: Optimise with 32 and 64b versions + _factor::(n) + }; + + if num == 1 { + return Factors::one(); + } + + let n = A::new(num); + let divisor = match miller_rabin::test::(n) { + Prime => { + return Factors::prime(num); + } + + Composite(d) => d, + Pseudoprime => rho::find_divisor::(n), + }; + + let mut factors = _factor(divisor); + factors *= _factor(num / divisor); + factors +} + pub fn factor(mut n: u64) -> Factors { let mut factors = Factors::one(); @@ -88,8 +116,10 @@ pub fn factor(mut n: u64) -> Factors { let (f, n) = table::factor(n); factors *= f; - if n >= table::NEXT_PRIME { - factors *= rho::factor(n); + if n < (1 << 32) { + factors *= _factor::(n); + } else { + factors *= _factor::(n); } factors diff --git a/src/uu/factor/src/rho.rs b/src/uu/factor/src/rho.rs index 9a53a40f4..b28e88e91 100644 --- a/src/uu/factor/src/rho.rs +++ b/src/uu/factor/src/rho.rs @@ -11,11 +11,9 @@ use rand::rngs::SmallRng; use rand::{thread_rng, SeedableRng}; use std::cmp::{max, min}; -use crate::miller_rabin::Result::*; use crate::numeric::*; -use crate::{miller_rabin, Factors}; -fn find_divisor(n: A) -> u64 { +pub(crate) fn find_divisor(n: A) -> u64 { #![allow(clippy::many_single_char_names)] let mut rand = { let range = Uniform::new(1, n.modulus()); @@ -47,33 +45,3 @@ fn find_divisor(n: A) -> u64 { } } } - -fn _factor(num: u64) -> Factors { - // Shadow the name, so the recursion automatically goes from “Big” arithmetic to small. - let _factor = |n| { - // TODO: Optimise with 32 and 64b versions - _factor::(n) - }; - - if num == 1 { - return Factors::one(); - } - - let n = A::new(num); - let divisor = match miller_rabin::test::(n) { - Prime => { - return Factors::prime(num); - } - - Composite(d) => d, - Pseudoprime => find_divisor::(n), - }; - - let mut factors = _factor(divisor); - factors *= _factor(num / divisor); - factors -} - -pub(crate) fn factor(n: u64) -> Factors { - _factor::(n) -}