use std::cmp::{Eq, PartialOrd};
use std::ops::{AddAssign, Div, DivAssign, Rem};
use num_traits::{One, Pow, Zero};
pub fn factor<T>(mut n: T) -> Vec<(T, usize)>
where
T: Zero + One + AddAssign + DivAssign + Eq + PartialOrd + Clone,
for<'a> &'a T: Pow<usize, Output = T>,
for<'b> T: DivAssign<&'b T>,
for<'a, 'b> &'a T: Div<&'b T, Output = T> + Rem<&'b T, Output = T>,
{
let mut pfs: Vec<(T, usize)> = Vec::new();
let mut d = T::one() + T::one();
while &n > &T::one() {
while (&n % &d) != T::zero() {
d += T::one();
}
let mut q = &n / &d;
let mut i = 1_usize;
while &q % &d == T::zero() {
q /= &d;
i += 1;
}
pfs.push((d.clone(), i));
n /= (&d).pow(i);
}
pfs
}