fn subfactors(mut n: u64, p: u64) -> (u64, Vec) { let mut subfactors = Vec::new(); let mut q = n / p; let mut r = n % p; while r == 0 { subfactors.push(p); n = q; q = n / p; r = n % p; } (n, subfactors) } pub fn trial_factorization(n: u64) -> Vec { let mut n = n; let mut factors = Vec::new(); let (num, division_by_two) = subfactors(n, 2); n = num; // is there a clean way to avoid this assignment? factors.extend(division_by_two); let (num, division_by_three) = subfactors(n, 3); n = num; factors.extend(division_by_three); let mut p = 5; while p * p <= n { let (num, division_by_p) = subfactors(n, p); n = num; factors.extend(division_by_p); p += 2; let (num, division_by_p_plus_two) = subfactors(n, p); n = num; factors.extend(division_by_p_plus_two); p += 4; } if n >= 1 { factors.push(n); } factors } fn root(n: u64, f: u64) -> u64 { let mut n = n; let mut result = 0; while n % f == 0 { result += 1; n /= f; } result } pub fn prime_factorization(n: u64) -> Vec<(u64, u64)> { let factors = trial_factorization(n); let exponents = factors.iter().map( |&f| root(n, f) ); factors.iter().zip(exponents).map( |(&i, j)| (i, j) ).collect() } #[cfg(test)] mod tests { use euler::prime::trial_factorization; #[test] fn test() { assert_eq!(trial_factorization(20).len(), 3); } }