There are quite a few things you can do. First - notice that a cube ending in an odd number must have started as an odd number - so only try odd numbers for M. Factor 2 in time saved.
Next - to find the last 3 digits of a number, just do number % 1000
. And don't use pow
. It is very slow. See my trick for finding the magnitude of the number.
You end up with something like this:
long int N, M, div;
printf("what is the value of N?\n");
scanf("%d", &N);
// test that it is reasonable before continuing...
// I did not write that code, but you should (size of N, and does it end in 1, 3, 7, or 9?
// find out how many digits N has:
div = 1;
while(N / div > 0) {
div *= 10;
}
// now loop around odd M
for(M = 1; M < div; M+=2) {
if( (M*M*M)%d==N) break;
}
// when you come out of this loop, M is the number you were looking for.
One final tweak - take a look at the cubes of numbers.
1*1*1 = 1
3*3*3 = 27
7*7*7 = 343
9*9*9 = 729
From this you conclude that if N
ends in 1
, you can check just numbers ending in 1
:
for(M=1; M<div; M+=10) {
similarly for the other values (3 - start with M=7; 7 - start with M=3; 9 - start with M=9). Now we have a factor 10x faster code...
May not be enough to win the competition but it should help...
EDIT just ran the following code, and it gave the same answer you had above in 0.02 seconds (after 10,000 times going around the algorithm) - that's about 20 microseconds to find M just once...
Note - updated m1
array so code should work even for "valid" numbers ending in 5
(although there is no guarantee that a number will exist - and the question explicitly asked about numbers ending in 1, 3, 7 and 9).
#include <stdio.h>
#include <time.h>
int main(void) {
long long int N, M, div;
long long int m1[] = {0, 1, 0, 7, 0, 5, 0, 3, 0, 9};
time_t start, end;
int ii;
printf("what is the value of N?\n");
scanf("%lld", &N);
// test that it is reasonable before continuing...
// I will leave that for you to do
start = clock();
// now starts the main loop
// I go around it 10,000 times to get a "reasonable accuracy" since the clock()
// function is not very granular (it was giving me "elapsed time zero")
// obviously for competition you want to do this just once!
for (ii = 0; ii < 10000; ii++) {
// find out how many digits N has:
div = 1;
while(N / div > 0) {
div *= 10;
}
// now try possible values of M - given the last digit of N
// we know what the last digit of M should be
// so we can start with that number, then take steps of 10
for(M = m1[N % 10]; M < div; M+=10) {
if( ( M * M * M ) % div == N ) break;
}
} // do it 10,000 times to get some time on the clock
// when you come out of this loop, M is the number you were looking for.
// since the loop stops at div, it should never be larger than N
printf("M is now %lld\n", M);
printf("M cubed is %lld which ends in %lld\n", M * M * M, ( M * M * M ) % div);
end = clock();
printf("Time taken: %f sec\n", ((float)(end - start) ) / CLOCKS_PER_SEC);
}