From 29f1b87841681f5437bcd18a8ff385aa1ce0607d Mon Sep 17 00:00:00 2001 From: Akhila Pynam Date: Sat, 17 Oct 2026 01:09:02 +0530 Subject: [PATCH] fix(math): modernize armstrong_number to fit contribution guidelines (#2456) --- math/armstrong_number.cpp | 127 ++++++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 45 deletions(-) diff --git a/math/armstrong_number.cpp b/math/armstrong_number.cpp index fd0d70a2a5..c16c058a35 100644 --- a/math/armstrong_number.cpp +++ b/math/armstrong_number.cpp @@ -4,79 +4,116 @@ * number](https://en.wikipedia.org/wiki/Narcissistic_number) in decimal system. * * @details - * Armstrong number or [Narcissistic - * number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that - * is the sum of its own digits raised to the power of the number of digits. + * An Armstrong number (also known as a pluperfect digital invariant (PPDI) or + * narcissistic number) is a number that is the sum of its own digits each + * raised to the power of the number of digits. * - * let n be the narcissistic number, - * \f[F_b(n) = \sum_{i=0}^{k-1}d_{i}^{k}\f] for - * \f$ b > 1 F_b : \N \to \N \f$ where - * \f$ k = \lfloor log_b n\rfloor is the number of digits in the number in base - * \f$b\f$, and \f$ d_i = \frac{n mod b^{i+1} - n mod b^{i}}{b^{i}} \f$ + * For example: + * - \f$153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153\f$ + * - \f$1634 = 1^4 + 6^4 + 3^4 + 4^4 = 1 + 1296 + 81 + 256 = 1634\f$ * * @author [Neeraj Cherkara](https://github.com/iamnambiar) + * @author [Akhila Pynam](https://github.com/akhila-pynam) */ + #include /// for assert -#include /// for std::pow +#include /// for std::uint64_t #include /// for IO operations /** - * @brief Function to calculate the total number of digits in the number. - * @param num Number - * @return Total number of digits. + * @namespace math + * @brief Mathematical algorithms + */ +namespace math { + +/** + * @brief Computes base raised to the power of exponent using integer + * arithmetic. + * @param base The base number. + * @param exp The exponent. + * @return base raised to the power of exp. + */ +uint64_t power(uint64_t base, uint64_t exp) { + uint64_t res = 1; + while (exp > 0) { + if (exp & 1) { + res *= base; + } + base *= base; + exp >>= 1; + } + return res; +} + +/** + * @brief Function to calculate the total number of digits in a number. + * @param num The number to count digits for. + * @return Total number of digits in the given number. */ -int number_of_digits(int num) { - int total_digits = 0; +uint64_t number_of_digits(uint64_t num) { + if (num == 0) { + return 1; + } + uint64_t total_digits = 0; while (num > 0) { - num = num / 10; + num /= 10; ++total_digits; } return total_digits; } /** - * @brief Function to check whether the number is armstrong number or not. - * @param number to be checked - * @return `true` if the number is armstrong. - * @return `false` if the number is not armstrong. + * @brief Function to check whether a number is an Armstrong number or not. + * @param number The number to be checked. + * @return `true` if the number is an Armstrong number. + * @return `false` if the number is not an Armstrong number. */ -bool is_armstrong(int number) { - // If the number is less than 0, then it is not an armstrong number. - if (number < 0) { - return false; - } +bool is_armstrong(uint64_t number) { + uint64_t total_digits = number_of_digits(number); + uint64_t sum = 0; + uint64_t temp = number; - int sum = 0; - int temp = number; - // Finding the total number of digits in the number - int total_digits = number_of_digits(number); while (temp > 0) { - int rem = temp % 10; - // Finding each digit raised to the power total digit and add it to the - // total sum - sum += static_cast(std::pow(rem, total_digits)); - temp = temp / 10; + uint64_t rem = temp % 10; + sum += power(rem, total_digits); + temp /= 10; } + return number == sum; } +} // namespace math + /** * @brief Self-test implementations * @returns void */ static void test() { - // is_armstrong(370) returns true. - assert(is_armstrong(370) == true); - // is_armstrong(225) returns false. - assert(is_armstrong(225) == false); - // is_armstrong(-23) returns false. - assert(is_armstrong(-23) == false); - // is_armstrong(153) returns true. - assert(is_armstrong(153) == true); - // is_armstrong(0) returns true. - assert(is_armstrong(0) == true); - // is_armstrong(12) returns false. - assert(is_armstrong(12) == false); + // 0 is an Armstrong number: 0^1 = 0 + assert(math::is_armstrong(0) == true); + + // Single-digit numbers are all Armstrong numbers: d^1 = d + assert(math::is_armstrong(1) == true); + assert(math::is_armstrong(5) == true); + assert(math::is_armstrong(9) == true); + + // 2-digit numbers are never Armstrong numbers in base 10 + assert(math::is_armstrong(10) == false); + assert(math::is_armstrong(12) == false); + + // 3-digit Armstrong numbers: 153, 370, 371, 407 + assert(math::is_armstrong(153) == true); + assert(math::is_armstrong(370) == true); + assert(math::is_armstrong(371) == true); + assert(math::is_armstrong(407) == true); + assert(math::is_armstrong(225) == false); + assert(math::is_armstrong(500) == false); + + // 4-digit Armstrong numbers: 1634, 8208, 9474 + assert(math::is_armstrong(1634) == true); + assert(math::is_armstrong(8208) == true); + assert(math::is_armstrong(9474) == true); + assert(math::is_armstrong(9475) == false); std::cout << "All tests have successfully passed!\n"; }