use cargo_snippet::snippet;
#[snippet("trial_division")]
fn firstfac(x: usize) -> usize {
if x % 2 == 0 {
return 2;
};
for n in (3..).step_by(2).take_while(|m| m * m <= x) {
if x % n == 0 {
return n;
};
}
x
}
#[snippet("trial_division")]
pub fn is_prime(n: usize) -> bool {
if n <= 1 {
return false;
}
firstfac(n) == n
}
#[test]
fn is_prime_test() {
assert_eq!(is_prime(2), true);
assert_eq!(is_prime(1), false);
assert_eq!(is_prime(3), true);
assert_eq!(is_prime(17), true);
assert_eq!(is_prime(1000000007), true);
}
#[snippet("trial_division")]
fn exp(n: &mut usize, d: usize) -> (usize, usize) {
let mut c = 0usize;
(
d,
loop {
if *n % d != 0 {
break c;
}
*n /= d;
c += 1;
},
)
}
#[snippet("trial_division")]
pub fn factorization(mut n: usize) -> Vec<(usize, usize)> {
let mut primes = Vec::new();
let (d, e) = exp(&mut n, 2);
if e > 0 {
primes.push((d, e));
}
let m = n;
for i in (3..).take_while(|x| *x * *x <= m).step_by(2) {
let (d, e) = exp(&mut n, i);
if e > 0 {
primes.push((d, e));
}
}
if n > 1 {
match primes.iter().enumerate().find(|x| (x.1).0 == n) {
Some((i, _)) => primes[i].1 += 1,
None => primes.push((n, 1)),
}
}
primes
}
#[test]
fn f_test() {
let f = factorization(13);
assert_eq!(f, vec![(13, 1)]);
let f = factorization(12);
assert_eq!(f, vec![(2, 2), (3, 1)]);
let f = factorization(1000000007);
assert_eq!(f, vec![(1000000007, 1)]);
}