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);