Skip to main content

nekolib/math/
digit_sum.rs

1//! 桁和。
2
3/// 桁和。
4///
5/// # Examples
6/// ```
7/// use nekolib::math::DigitSum;
8///
9/// assert_eq!(2_u32.pow(15).digit_sum(10), 3 + 2 + 7 + 6 + 8);
10/// assert_eq!(123_u32.digit_pow_sum(10, 2), 1*1 + 2*2 + 3*3);
11/// assert_eq!(0xACE_u32.digit_sum(16), 0xA + 0xC + 0xE);
12///
13/// assert_eq!(12345_u32.digit_pow_sum(10, 0), 5);  // the number of digits
14/// assert_eq!(0_u32.digit_pow_sum(10, 0), 1);
15/// ```
16pub trait DigitSum: Sized {
17    fn digit_pow_sum(self, base: Self, exp: u32) -> Self;
18    fn digit_sum(self, base: Self) -> Self { self.digit_pow_sum(base, 1) }
19}
20
21macro_rules! impl_uint {
22    ($t:ty) => {
23        impl DigitSum for $t {
24            fn digit_pow_sum(mut self, base: Self, exp: u32) -> Self {
25                if self == 0 {
26                    return if exp == 0 { 1 } else { 0 };
27                }
28                let mut res = 0;
29                while self > 0 {
30                    res += (self % base).pow(exp);
31                    self /= base;
32                }
33                res
34            }
35        }
36    };
37    ( $($t:ty)* ) => { $(impl_uint!($t);)* };
38}
39
40impl_uint!(u8 u16 u32 u64 u128 usize);