A similar saying is there for software engineers: you can't optimize what you can't measure. There are several ways to measure your code, e.g. benchmarking, profiling, or looking at the generated assemblerassembler to see how many instructions a certain part of your code will take.
…
a = 1, b = 1, c = 463000, time = 0.031000s
a = 1, b = 1, c = 464000, time = 0.031000s
a = 1, b = 1, c = 465000, time = 0.031000s
a = 1, b = 1, c = 466000, time = 0.031000s
a = 1, b = 1, c = 467000, time = 0.031000s
a = 1, b = 1, c = 468000, time = 0.031000s
a = 1, b = 1, c = 469000, time = 0.031000s
a = 1, b = 1, c = 470000, time = 0.031000s
a = 1, b = 1, c = 471000, time = 0.031000s
a = 1, b = 1, c = 472000, time = 0.031000s
a = 1, b = 1, c = 473000, time = 0.031000s
a = 1, b = 1, c = 474000, time = 0.031000s
a = 1, b = 1, c = 475000, time = 0.031000s
a = 1, b = 1, c = 476000, time = 0.031000s
a = 1, b = 1, c = 477000, time = 0.031000s
a = 1, b = 1, c = 478000, time = 0.031000s
a = 1, b = 1, c = 479000, time = 0.031000s
a = 1, b = 1, c = 480000, time = 0.031000s
a = 1, b = 1, c = 481000, time = 0.031000s
a = 1, b = 1, c = 482000, time = 0.031000s
a = 1, b = 1, c = 483000, time = 0.031000s
a = 1, b = 1, c = 484000, time = 0.031000s
a = 1, b = 1, c = 485000, time = 0.031000s
a = 1, b = 1, c = 486000, time = 0.031000s
a = 1, b = 1, c = 487000, time = 0.031000s
a = 1, b = 1, c = 488000, time = 0.031000s
a = 1, b = 1, c = 489000, time = 0.031000s
a = 1, b = 1, c = 490000, time = 0.031000s
a = 1, b = 1, c = 491000, time = 0.031000s
a = 1, b = 1, c = 492000, time = 0.031000s
a = 1, b = 1, c = 493000, time = 0.031000s
a = 1, b = 1, c = 494000, time = 0.031000s
a = 1, b = 1, c = 495000, time = 0.031000s
a = 1, b = 1, c = 496000, time = 0.031000s
a = 1, b = 1, c = 497000, time = 0.031000s
a = 1, b = 1, c = 498000, time = 0.031000s
a = 1, b = 1, c = 499000, time = 0.031000s
a = 1, b = 1, time = 0.031000s
Types
Given that all values should be strictly greater than zero, long int
is not the appropriate type, as it can be negative. We should accommodate that. However, instead of using long unsigned int
throughout our code, let's use a type synonym in case we want to change it later to a type with a greater range:
typedef long unsigned int Number;
You can probably come up with a better name.
Remember how I said that nicely written, modular code isn't often optimal? This is one of those unfortunateunfortunate examples where you have to help the compiler (unless you know exactly what optimization flags you have to use or your compiler is overly aggressive). The prop
is gone, the calls to pow4
are now in your loop.
That being said, we should apply the other suggestions like the type synonym and the late declaration:
typedef long unsigned int Number;
int main() {
clock_t t;
t = clock();
for (Number a = 1; a < 100000; a++) {
const Number a4 = pow4(a); // remember
for (Number b = a; b < 300000; b++) {
const Number b4 = pow4(b); // remember
for (Number c = b; c < 500000; c++) {
const Number c4 = pow4(c); // the fourth power
for (Number d = c; d < 500000; d++) {
const Number d4 = pow4(d); // of this member
if (a4 + b4 + c4 == d4)
printf("FOUND IT!\na = %ld\nb = %ld\nc = %ld\nd = %ld\n", a, b, c, d);
…
While const
isn't necessary here, it will make sure that we don't change our cached results accidentally.