mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-04 23:17:46 +00:00
factor: Move recursive factoring logic from rho to factor
No functional change, but prepares a coming optimisation.
This commit is contained in:
parent
bd4d6fcac5
commit
6713d2ad62
2 changed files with 33 additions and 35 deletions
|
@ -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<A: Arithmetic>(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::<A>(n)
|
||||
};
|
||||
|
||||
if num == 1 {
|
||||
return Factors::one();
|
||||
}
|
||||
|
||||
let n = A::new(num);
|
||||
let divisor = match miller_rabin::test::<A>(n) {
|
||||
Prime => {
|
||||
return Factors::prime(num);
|
||||
}
|
||||
|
||||
Composite(d) => d,
|
||||
Pseudoprime => rho::find_divisor::<A>(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::<Montgomery>(n);
|
||||
} else {
|
||||
factors *= _factor::<Montgomery>(n);
|
||||
}
|
||||
|
||||
factors
|
||||
|
|
|
@ -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<A: Arithmetic>(n: A) -> u64 {
|
||||
pub(crate) fn find_divisor<A: Arithmetic>(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<A: Arithmetic>(n: A) -> u64 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn _factor<A: Arithmetic>(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::<A>(n)
|
||||
};
|
||||
|
||||
if num == 1 {
|
||||
return Factors::one();
|
||||
}
|
||||
|
||||
let n = A::new(num);
|
||||
let divisor = match miller_rabin::test::<A>(n) {
|
||||
Prime => {
|
||||
return Factors::prime(num);
|
||||
}
|
||||
|
||||
Composite(d) => d,
|
||||
Pseudoprime => find_divisor::<A>(n),
|
||||
};
|
||||
|
||||
let mut factors = _factor(divisor);
|
||||
factors *= _factor(num / divisor);
|
||||
factors
|
||||
}
|
||||
|
||||
pub(crate) fn factor(n: u64) -> Factors {
|
||||
_factor::<Montgomery>(n)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue