1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! 約数列挙。

/// 約数列挙。
///
/// # Complexity
/// $O(\\sqrt{n})$ time, $O(1)$ space.
///
/// # Examples
/// ```
/// use nekolib::math::Divisors;
///
/// let div: Vec<_> = 60_u64.divisors().collect();
/// assert_eq!(div, [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60]);
/// ```
pub trait Divisors {
    type Output;
    fn divisors(self) -> Self::Output;
}

pub struct DivisorsStruct<I> {
    below: bool,
    i: I,
    n: I,
}

macro_rules! impl_divisors_uint {
    ( $($ty:ty)* ) => { $(
        impl Divisors for $ty {
            type Output = DivisorsStruct<$ty>;
            fn divisors(self) -> Self::Output {
                Self::Output { below: true, i: 0, n: self }
            }
        }
        impl DivisorsStruct<$ty> {
            fn increment(&mut self) -> Option<$ty> {
                if !self.below {
                    return None;
                }
                loop {
                    self.i += 1;
                    let ii = if let Some(ii) = self.i.checked_pow(2) {
                        ii
                    } else {
                        self.below = false;
                        return None;
                    };
                    if ii >= self.n {
                        self.below = false;
                        if ii > self.n {
                            return None;
                        }
                    }
                    if self.n % self.i == 0 {
                        return Some(self.i);
                    }
                }
            }
            fn decrement(&mut self) -> Option<$ty> {
                while self.i > 1 {
                    self.i -= 1;
                    if self.n % self.i == 0 {
                        return Some(self.n / self.i);
                    }
                }
                None
            }
        }
        impl Iterator for DivisorsStruct<$ty> {
            type Item = $ty;
            fn next(&mut self) -> Option<$ty> {
                self.increment().or_else(|| self.decrement())
            }
        }
    )* };
}

impl_divisors_uint! { u8 u16 u32 u64 u128 usize }

#[test]
fn test() {
    let n = 10000_u64;
    for i in 0..=n {
        let actual: Vec<_> = i.divisors().collect();
        let expected: Vec<_> = (1..=i).filter(|&j| i % j == 0).collect();
        assert_eq!(actual, expected);
    }
}

#[test]
fn overflow() {
    for i in (1_u32..=1000)
        .flat_map(|i| [i.wrapping_neg(), 2_u32.pow(16) * (2_u32.pow(16) - i)])
    {
        let actual: Vec<_> = i.divisors().collect();
        let expected: Vec<_> =
            (i as u64).divisors().map(|d| d as u32).collect();
        assert_eq!(actual, expected);
    }
}

#[test]
fn overflow_exhaustive() {
    for i in u8::MIN..=u8::MAX {
        let actual: Vec<_> = i.divisors().collect();
        let expected: Vec<_> = (i as u32).divisors().map(|d| d as u8).collect();
        assert_eq!(actual, expected);
    }
    for i in u16::MIN..=u16::MAX {
        let actual: Vec<_> = i.divisors().collect();
        let expected: Vec<_> =
            (i as u32).divisors().map(|d| d as u16).collect();
        assert_eq!(actual, expected);
    }
}