#Using Euler Project 145 to Teach Myself C
15 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.
This is Euler Project 145:
My code is as follows:```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int reverse_n(int n) {
int digit_count = (int) ceil(log10(n));
if (n == 0 || n == 1) {
digit_count = 1;
}
char n_str[digit_count + 1];
char m_str[digit_count + 1];
sprintf(n_str, "%d", n);
int j = digit_count - 1;
for (int i = 0; i < digit_count; i++) {
m_str[j] = n_str[i];
j--;
}
m_str[digit_count + 1] = '\0';
int m = atoi(m_str);
return m;
}
int test_n(int n) {
int sum = n + reverse_n(n);
int digit_count = (int) ceil(log10(sum));
for (int i = 0; i < digit_count; i++) {
if (sum % 2 == 0) {
return 0;
}
sum /= 10;
}
return 1;
}
int main() {
int count = 0;
for (int i = 1; i < 1000; i++) {
count += test_n(i);
printf("n: %3i, reversed: %3i, sum: %4i, test: %i, total: %i\n", i, reverse_n(i), i + reverse_n(i), test_n(i), count);
}
printf("%i\n", count);
}
Now, one of the pieces of information that the Euler Project provides is that there are 120 reversible numbers for n < 1000. When I run this code, the answer I come up with is 125. This is confusing to me because that means there is some special case that I am not accounting for.
i've yet to read throught all of your code - but m_str[digit_count + 1] = '\0'; is UB (undefied behavior and thus isn't allowed). a kind reminder array indices starts at 0
as for the problem - since you're counting numbers being added to themselves (e.g. thats incorrect11 + 11) it might mess with your results
after fixing the above mentioned problem (and cleaning up a bit) - the algo seems to be correct. unless there're not restrictions not listed in the pic you posted - 125 seems to be correct
If you eliminate numbers that end in 0 because once reversed, it would be a leading zero, you get 120.
ah. they should have communicated it a bt more clearly
Agreed. Eliminating string stuff and optimizing code a bit, the brute force calculation for 1 billion:
$ time ./a.out
Final count: 608720
real 0m46.736s
user 0m46.698s
sys 0m0.001s
Optimizing some more by using OpenMp:
#include <omp.h> // Required for OpenMP
#pragma omp parallel for reduction(+:count)
for (int i = 0; i < 1000000000; i++) {
count += test_n(i);
}
$ gcc -O3 -fopenmp testReversibleOpt.c
$ time ./a.out
Final count: 608720
real 0m5.865s
user 0m22.949s
sys 0m0.007s
How is the real time less than the userspace time?
Is it cause it's counting userspace time from all cores individually?
Correct. split the processing across all cores.
Probably also some SIMD, my beloved :D, parts