Skip to content

Commit

Permalink
factor: Ensure we only need to find every single factor once [WiP]
Browse files Browse the repository at this point in the history
~17% faster, many optimisation opportunities still missed  >:)
  • Loading branch information
nbraud authored and rivy committed Oct 26, 2020
1 parent 3743a3e commit ce218e0
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions src/uu/factor/src/factor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern crate rand;
use std::cell::RefCell;
use std::fmt;

use crate::numeric::{Arithmetic, Montgomery};
use crate::numeric::{gcd, Arithmetic, Montgomery};
use crate::{miller_rabin, rho, table};

type Exponent = u8;
Expand Down Expand Up @@ -164,8 +164,42 @@ pub fn factor(num: u64) -> Factors {
let (f, e) = dec.pop().unwrap();

if let Some(d) = find_factor(f) {
dec.add(f / d, e);
dec.add(d, e);
let mut gcd_queue = Decomposition::one();
gcd_queue.add(d, e);
gcd_queue.add(f / d, e);

let mut non_trivial_gcd = true;
while non_trivial_gcd {
debug_assert_eq!(f, gcd_queue.product());

let mut tmp = Decomposition::one();
non_trivial_gcd = false;
for i in 0..gcd_queue.0.len() - 1 {
let (a, e_a) = gcd_queue.0[i];
let (b, e_b) = gcd_queue.0[i + 1];

let g = gcd(a, b);
if g != 1 {
non_trivial_gcd = true;
tmp.add(a / g, e_a);
tmp.add(g, e_a + e_b);
if i + 1 == gcd_queue.0.len() {
tmp.add(b / g, e_b)
} else {
gcd_queue.0[i + 1] = (b / g, e_b);
}
} else {
tmp.add(a, e_a);
if i + 1 == gcd_queue.0.len() - 1 {
tmp.add(b, e_b)
}
}
}
gcd_queue = tmp;
}

debug_assert_eq!(f, gcd_queue.product());
dec.0.extend(gcd_queue.0);
} else {
// f is prime
factors.add(f, e);
Expand Down

0 comments on commit ce218e0

Please sign in to comment.