@@ -248,6 +248,7 @@ number_impl! {float => f32, f64}
248248/// assert_eq!(is_prime(123u32), false);
249249/// ```
250250#[ inline]
251+ #[ must_use]
251252pub fn is_prime < T : UnsignedInteger > ( n : T ) -> bool {
252253 if n <= T :: ONE {
253254 return false ;
@@ -277,6 +278,54 @@ pub fn is_prime<T: UnsignedInteger>(n: T) -> bool {
277278 true
278279}
279280
281+ /// Computes the sum of the divisors for unsigned integer `n`.
282+ ///
283+ /// Returns `None` if the sum overflows.
284+ ///
285+ /// # Examples
286+ /// ```
287+ /// # use utils::number::sum_of_divisors;
288+ /// assert_eq!(sum_of_divisors(5u32), Some(6));
289+ /// assert_eq!(sum_of_divisors(32u32), Some(63));
290+ /// assert_eq!(sum_of_divisors(50u32), Some(93));
291+ /// assert_eq!(sum_of_divisors(857_656_800u32), None);
292+ /// assert_eq!(sum_of_divisors(857_656_800u64), Some(4_376_251_152));
293+ /// ```
294+ #[ inline]
295+ #[ must_use]
296+ pub fn sum_of_divisors < T : UnsignedInteger > ( n : T ) -> Option < T > {
297+ if n <= T :: ONE {
298+ return Some ( n) ;
299+ }
300+
301+ let mut sum = T :: ZERO ;
302+ let mut d = T :: ONE ;
303+ while let Some ( square) = d. checked_mul ( d)
304+ && square <= n
305+ {
306+ if n % d == T :: ZERO {
307+ if let Some ( s) = sum. checked_add ( d) {
308+ sum = s;
309+ } else {
310+ return None ;
311+ }
312+
313+ let q = n / d;
314+ if q != d {
315+ if let Some ( s) = sum. checked_add ( q) {
316+ sum = s;
317+ } else {
318+ return None ;
319+ }
320+ }
321+ }
322+
323+ d += T :: ONE ;
324+ }
325+
326+ Some ( sum)
327+ }
328+
280329/// Computes the greatest common divisor (GCD) using the extended Euclidean algorithm.
281330///
282331/// Returns a tuple `(gcd, x, y)` where `x`, `y` are the coefficients of Bézout's identity:
@@ -291,6 +340,7 @@ pub fn is_prime<T: UnsignedInteger>(n: T) -> bool {
291340/// assert_eq!((252 * -2) + (105 * 5), 21);
292341/// ```
293342#[ inline]
343+ #[ must_use]
294344pub fn egcd < T : SignedInteger > ( mut a : T , mut b : T ) -> ( T , T , T ) {
295345 let ( mut x0, mut x1, mut y0, mut y1) = ( T :: ONE , T :: ZERO , T :: ZERO , T :: ONE ) ;
296346
@@ -312,6 +362,8 @@ pub fn egcd<T: SignedInteger>(mut a: T, mut b: T) -> (T, T, T) {
312362/// assert_eq!(lcm(6, 4), 12);
313363/// assert_eq!(lcm(21, 6), 42);
314364/// ```
365+ #[ inline]
366+ #[ must_use]
315367pub fn lcm < T : SignedInteger > ( a : T , b : T ) -> T {
316368 if a == T :: ZERO || b == T :: ZERO {
317369 return T :: ZERO ;
@@ -335,6 +387,7 @@ pub fn lcm<T: SignedInteger>(a: T, b: T) -> T {
335387/// assert_eq!(mod_inverse(2, 8), None);
336388/// ```
337389#[ inline]
390+ #[ must_use]
338391pub fn mod_inverse < T : SignedInteger > ( a : T , b : T ) -> Option < T > {
339392 let ( gcd, x, _) = egcd ( a, b) ;
340393 if gcd == T :: ONE {
@@ -358,6 +411,7 @@ pub fn mod_inverse<T: SignedInteger>(a: T, b: T) -> Option<T> {
358411/// assert_eq!(366 % 11, 3);
359412/// ```
360413#[ inline]
414+ #[ must_use]
361415pub fn chinese_remainder < T : SignedInteger > (
362416 residues : impl IntoIterator < Item = T > ,
363417 moduli : impl IntoIterator < Item = T , IntoIter : Clone > ,
@@ -383,6 +437,7 @@ pub fn chinese_remainder<T: SignedInteger>(
383437/// assert_eq!(mod_pow::<u64>(65, 100000, 2147483647), 1085966926);
384438/// ```
385439#[ inline]
440+ #[ must_use]
386441pub fn mod_pow < T : UnsignedInteger > ( base : T , exponent : T , modulus : T ) -> T {
387442 let mut result = T :: ONE ;
388443 let mut base = base % modulus;
0 commit comments