Skip to content

How to Take a Number and Sum It’s Digits Raied to the Consecutive Powers in C

The challenge

The number 89 is the first integer with more than one digit that fulfills the property partially introduced in the title of this challenge. What’s the use of saying “Eureka”? Because this sum gives the same number.

In effect: 89 = 8^1 + 9^2

The next number in having this property is 135.

See this property again: 135 = 1^1 + 3^2 + 5^3

We need a function to collect these numbers, that may receive two integers ab that defines the range [a, b] (inclusive) and outputs a list of the sorted numbers in the range that fulfills the property described above.

Let’s see some cases (input -> output):

1, 10 -> [1, 2, 3, 4, 5, 6, 7, 8, 9] 1, 100 -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 89]
Code language: plaintext (plaintext)

If there are no numbers of this kind in the range [a, b] the function should output an empty list.

90, 100 --> []
Code language: plaintext (plaintext)

The solution in C

Option 1:

#include <stddef.h> #include <math.h> typedef unsigned long long ull; ull *sum_dig_pow(ull a, ull b, ull *results, size_t *length) { int place = ; for (int i = a; i <= b; i++) { int k = ; k = log10(i) + 1; if (pow((i % 10), k) > i) i = i + (10 - (i % 10)); else { int op = i; int sum = ; for (int m = k; m > ; m--) { sum += pow(op % 10, m); op /= 10; } if (sum == i) { results[place] = i; place++; } } } *length = place; return results; }
Code language: C++ (cpp)

Option 2:

#include <stddef.h> typedef unsigned long long ull; ull *sum_dig_pow(ull a, ull b, ull *r, size_t *rl) { // A032799 static const ull A[20] = {, 1, 2, 3, 4, 5, 6, 7, 8, 9, 89, 135, 175, 518, 598, 1306, 1676, 2427, 2646798, 12157692622039623539ull}; size_t i; for(*rl = i = ; i < 20 && A[i] <= b; i++) { if(a <= A[i]) { r[(*rl)++] = A[i]; } } return r; }
Code language: C++ (cpp)

Option 3:

#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> typedef unsigned long long ull; ull *sum_dig_pow (ull a, ull b, ull *results, size_t *length) { char str [snprintf (NULL, , "%llu", b) + 1]; for (*length = ; a <= b; a++) { sprintf (str, "%llu", a); ull sum = ; for (size_t digit = ; digit < strlen (str); digit++) sum += (ull) pow (*(str + digit) - '0', digit + 1); if (sum == a) *(results + (*length)++) = a; } return results; }
Code language: C++ (cpp)

Test cases to validate our solution

#include <criterion/criterion.h> #include <stddef.h> #include <stdio.h> typedef unsigned long long ull; ull *sum_dig_pow(ull a, ull b, ull *results, size_t *length); void tester(ull a, ull b, size_t e_len, ull expected[e_len]); Test(sum_dig_pow, Sample_Tests) { { ull a = 1; ull b = 10; const ull expected[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; tester(a, b, 9, (ull *)expected); } { ull a = 1; ull b = 100; const ull expected[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 89}; tester(a, b, 10, (ull *)expected); } { ull a = 10; ull b = 100; const ull expected[1] = {89}; tester(a, b, 1, (ull *)expected); } { ull a = 90; ull b = 100; const ull *expected = NULL; tester(a, b, , (ull *)expected); } { ull a = 90; ull b = 150; const ull expected[1] = {135}; tester(a, b, 1, (ull *)expected); } { ull a = 50; ull b = 150; const ull expected[2] = {89, 135}; tester(a, b, 2, (ull *)expected); } { ull a = 10; ull b = 150; const ull expected[2] = {89, 135}; tester(a, b, 2, (ull *)expected); } } void tester(ull a, ull b, size_t exp_len, ull expected[exp_len]) { ull results[exp_len]; for(size_t i=; i<exp_len; i++) { results[i] = rand() - rand(); } size_t sub_len = ; ull *submitted = sum_dig_pow(a, b, (ull *)results, &sub_len); if(sub_len != exp_len) { cr_assert_fail( "< Incorrect Output Length >\n \nSubmitted: %zu\nExpected: %zu\n \n", sub_len, exp_len ); } for(size_t i=; i<exp_len; i++) { if(submitted[i] != expected[i]) { char sub_str[7 * sub_len + 1]; size_t s = , p = sprintf(sub_str, "{"); while(s < sub_len) p += sprintf(sub_str + p, "%llu, ", submitted[s++]); sprintf(sub_str + p - 2, "}"); char exp_str[7 * exp_len + 1]; size_t e = , q = sprintf(exp_str, "{"); while(e < exp_len) q += sprintf(exp_str + q, "%llu, ", expected[e++]); sprintf(exp_str + q - 2, "}"); cr_assert_fail( "< Incorrect Value(s) >\n \na = %llu\nb = %llu\n \nSubmitted: %s\nExpected: %s\n \n", a, b, sub_str, exp_str ); } } cr_assert(1); }
Code language: C++ (cpp)

See also  How to Convert a String to an Integer in C
Tags:
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x