acm/
divisors.rs

1use std::cmp::{Eq, PartialOrd};
2use std::ops::{AddAssign, Div, DivAssign, Mul, Rem};
3
4use num_traits::{One, Pow, Zero};
5
6use crate::factor::factor;
7
8/// Returns the integer divisors of an integer.
9///
10/// # Examples
11/// ```
12/// assert_eq!(acm::divisors::divisors(60), vec![1, 2, 4, 3, 6, 12, 5, 10, 20, 15, 30, 60]);
13/// ```
14pub fn divisors<T>(n: T) -> Vec<T>
15where
16    T: Zero + One + AddAssign + DivAssign + Eq + PartialOrd + Clone,
17    for<'a> &'a T: Mul<T, Output = T> + Pow<usize, Output = T>,
18    for<'b> T: DivAssign<&'b T>,
19    for<'a, 'b> &'a T: Div<&'b T, Output = T> + Rem<&'b T, Output = T>,
20{
21    let mut res = vec![T::one()];
22    for (factor, m) in factor(n).iter() {
23        for d in res.clone() {
24            for p in 1..m + 1 {
25                res.push(&d * factor.pow(p));
26            }
27        }
28    }
29    res
30}