competitive_hpp/utils/
digit.rs1pub 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}