competitive_hpp/utils/
digit.rs

1pub trait DigitUtils {
2    fn digit(self) -> u32;
3    fn leftmost_digit(self) -> Self;
4    fn rightmost_digit(self) -> Self;
5    fn nth_digit(self, n: u32) -> Self;
6    fn digit_sum(self) -> Self;
7}
8
9macro_rules! impl_digit_utils(($($ty:ty),*) => {
10    $(
11        impl DigitUtils for $ty {
12            #[inline]
13            fn digit(self) -> u32 {
14                (self as f64).log10().trunc() as u32 + 1
15            }
16
17            #[inline]
18            fn leftmost_digit(self) -> Self {
19                (self / (10 as Self).pow(self.digit() - 1))
20            }
21
22            #[inline]
23            fn rightmost_digit(self) -> Self {
24                (self % 10)
25            }
26
27            #[inline]
28            fn nth_digit(self, n:u32) -> Self {
29                ((self / (10 as Self).pow(n - 1)) % 10)
30            }
31
32            #[inline]
33            fn digit_sum(self) -> Self {
34                (0..self.digit()).fold((0, self),|(sum, x), _| (sum + x%10, x/10)).0
35            }
36        }
37    )*
38});
39
40impl_digit_utils!(u64, u32, i64, i32, usize, isize, u128, i128);
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45
46    macro_rules! impl_digit_utils_test(($ty:ty) => {
47        assert_eq!((1 as $ty).digit(), 1);
48        assert_eq!((12 as $ty).digit(), 2);
49        assert_eq!((1 as $ty).leftmost_digit(), 1);
50        assert_eq!((200 as $ty).leftmost_digit(), 2);
51
52        assert_eq!((10 as $ty).rightmost_digit(), 0);
53        assert_eq!((202 as $ty).rightmost_digit(), 2);
54
55        assert_eq!((4321 as $ty).nth_digit(1), 1);
56        assert_eq!((4321 as $ty).nth_digit(2), 2);
57        assert_eq!((4321 as $ty).nth_digit(3), 3);
58
59        assert_eq!((1234 as $ty).digit_sum(), 10);
60    });
61
62    #[test]
63    fn u64_digit_test() {
64        impl_digit_utils_test!(u64);
65    }
66
67    #[test]
68    fn u32_digit_test() {
69        impl_digit_utils_test!(u32);
70    }
71    #[test]
72    fn i64_digit_test() {
73        impl_digit_utils_test!(i64);
74    }
75    #[test]
76    fn i32_digit_test() {
77        impl_digit_utils_test!(i32);
78    }
79    #[test]
80    fn usize_digit_test() {
81        impl_digit_utils_test!(usize);
82    }
83    #[test]
84    fn isize_digit_test() {
85        impl_digit_utils_test!(isize);
86    }
87}