The following is a solution to Project Euler problem number 12: which is to find the first triangular number with more than 500 divisors.
The code takes far too long to complete (over 10 minutes). Is there any way to optimize the run-time and to make it more elegant?
#include <iostream>
#include <chrono>
#include <ctime>
inline void triangle(int &num, int &interval)
{
num = ((interval * interval) + interval ) / 2;
}
int main()
{
long int input;
int num = 1, interval = 1, divisor = 1, no_divisor = 0;
std::cout << "Enter factor limit for Triangle number: ";
std::cin >> input;
auto start = std::chrono::steady_clock::now();
for (;;)
{
while (divisor <= num)
{
if (0 == num % divisor) //check factor;
{
std::cout << "factor: " << divisor << "\n";
no_divisor++;
if (no_divisor > input) //divisor count over input number, jump to exit;
{
goto exit;
}
}
divisor++;
}
std::cout << "\n";
interval++;
triangle(num, interval);
divisor = 1; //reset divisor back to 1;
no_divisor = 0; //reset divisor count back to 0;
}
exit: std::cout << "the first Triangle number to have over " << input << " divisors : " << num << "\n";
auto end = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "\nIt took me " << elapsed.count() << " milliseconds." << "\n";
return 0;
}
Optimization I've done:
- using
std::cout << "\n"
instead ofstd::cout << endl
to prevent flushing output buffers. Source: this - using
inline void triangle(int &num, int &interval)
speed up 10% time - using n(n+1)/2 according to this
Speculation:
I figured if the question asked for over 500 factors, which for example: Triangular number 28 has over 5 factors:
So I only need to iterate up to half of the limit. But how can I implement that into my code to only iterate up to half as many factor?
n
andn+1
(first divide the even one by 2); they are coprime and thus have mutually exclusive factors sond(n*(n+1))=nd(n)*nd(n+1)
\$\endgroup\$