So, has it anything to do with Arduino? Well, I wanted to write some C code that searched for this kind of numbers. But the only C editor I had was an Arduino. So I actually made the Arduino search these numbers for me, writing the results to the serial monitor.
Brute force. Being smart doesn't require code. Here's the last version. I just changed the code when I went from 4 to 5 or 6 digits, or when I changed the exponent.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
long d6, d5, d4, d3, d2, d1;
for (long i = 100000; i < 1000000; i++)
{
d6 = i / 100000;
d5 = (i % 100000) / 10000;
d4 = (i % 10000) / 1000;
d3 = (i % 1000) / 100;
d2 = (i % 100) / 10;
d1 = (i % 10);
if ((d6*d6*d6*d6*d6*d6 + d5*d5*d5*d5*d5*d5 + d4*d4*d4*d4*d4*d4 + d3*d3*d3*d3*d3*d3 + d2*d2*d2*d2*d2*d2 + d1*d1*d1*d1*d1*d1) == i)
Serial.println(i);
}
}
I admit, it looks stupid to write the thing in the loop() function, but this was a quickhack.
Actually, I had a Seeeduino XIAO, and it doesn't have a reset button. So, when I had the program in setup(), it ran before I got to open the serial monitor. I don't know every detail about the serial, but it looks like it didn't go to any queue waiting for the monitor to open. So I put it on loop instead.
And it indeed is brute force. It goes through all numbers from say 10000 to 99999. But it should be more clever. If say it checks number 8202 and finds out that 8⁴ + 2⁴ + 0⁴ + 2⁴ equals 4128, it could skip some numbers, because we know 4128 is 4074 less than 8202. Should we check 8203? No, because 3⁴ is not that much more than 2⁴.
x⁴ = 4074
x = 7.9 something. So we could skip from 8202 to at least 8207.
Anyway, this forum name is Bar Sport, so feel free to use these number in real life bar sport.
It's fun, so I wanted to try and go through multiple length without modifying the code
void setup() {
Serial.begin(115200);
while (!Serial);
for (int exponent = 3; exponent < 9; exponent++) {
int digits[exponent];
char number[exponent + 1];
Serial.printf("Searching with %d digits\n", exponent);
for (long long v = pow(10, exponent - 1); v < pow(10, exponent) - 1; v++) {
lltoa(v, number, 10);
for (int i = 0; i < exponent; i++) digits[i] = number[i] - '0';
long long r = 0;
for (int i = 0; i < exponent; i++) {
r += pow(digits[i], exponent);
if (r > v) break;
}
if (r == v) {
Serial.print(v);
Serial.print("\t[");
Serial.print(millis() / 1000.0, 2);
Serial.println(" s]");
}
}
}
}
void loop() {}
I took the code to my Mac because I was tired of waiting
good news, it gives the same numbers as you
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main ( int argc , char * argv[] ) {
for (int exponent = 3; exponent < 10; exponent++) {
int digits[exponent];
char number[exponent + 1];
printf("Searching with %d digits\n", exponent);
for (long long v = pow(10.0, exponent - 1.0); v < pow(10.0, exponent) - 1; v++) {
sprintf(number, "%lld", v);
for (int i = 0; i < exponent; i++) digits[i] = number[i] - '0';
long long r = 0;
for (int i = 0; i < exponent; i++) {
r += pow(digits[i], exponent);
if (r > v) break;
}
if (r == v) printf("%lld\n", v);
}
}
printf("that's all I've got for now.");
return 0 ;
}
Searching with 3 digits
153
370
371
407
Searching with 4 digits
1634
8208
9474
Searching with 5 digits
54748
92727
93084
Searching with 6 digits
548834
Searching with 7 digits
1741725
4210818
9800817
9926315
Searching with 8 digits
24678050
24678051
88593477
Searching with 9 digits
146511208
472335975
534494836
912985153
that's all I've got for now.
PS: noticed you got 1⁵ + 9⁵ + 4⁵ + 9⁵ + 7⁵ + 9⁵ which works but that's 6 digits for a power of 5. does it count?
Well, if you want it to count. Sure your numbers are more elegant, because the exponent equals the number of digits. But with 9 digits you don't see at a glance that there are 9 digits. But you still see at a glance that the result sum has the same digits as what you started with, which is the actual point of this.
But much faster, table up an array of 10 longs, 1 for each digit to the whatever power and don't forget that Arduino supports 64 bit integers. Also why not go unsigned for this?
Be careful when using arduino's pow() function.
It does not return an integer number but a double number;
The result of the exponentiation. Datatype: double.
Look at the result of this simple example:
Code:
void setup() {
Serial.begin(115200);
delay(100);
for (int k = 0; k < 4; k++)
{
double c = pow(k, 2);
Serial.print( k); Serial.print( " power of two = "); Serial.println (c,0);
}
Serial.println( "");
for (int k = 0; k < 4; k++)
{
int c = pow(k, 3);
Serial.print( k); Serial.print( " power of three = "); Serial.println (c);
}
Serial.println( "");
for (int k = 0; k < 4; k++)
{
double c = pow(k, 3);
Serial.print( k); Serial.print( " power of three = "); Serial.println (c,0);
}
}
void loop() {}
Results:
0 power of two = 0
1 power of two = 1
2 power of two = 4
3 power of two = 9
0 power of three = 0 result using int
1 power of three = 1
2 power of three = 7
3 power of three = 26
0 power of three = 0 result using double
1 power of three = 1
2 power of three = 8
3 power of three = 27
Arduino double is Arduino float, 6 digit precision guaranteed, runs very slow on AVR.
The Arduino pow() function expects floating point input.
When you set a float = an int, often 2 becomes 1.99999.... and when you print
Serial.println (c,0);
it cuts everything after the dec pt off, word is truncate.
PRE-calculate everything you can and stuff it in tables. A 10x4 2D table of unsigned ints could hold digits 0 to 9 squared in row 0 up to the 5th power in row 3. 9^5 = 59049
AVR lets you write tables to flash, on an Uno that is 32K - your sketch code = usually over 24K while there is 2K RAM. Look Up Tables are enormously fast and can save RAM.