project-euler

https://projecteuler.net/
Log | Files | Refs | README

commit 644a8c74c30a358d8b91711d990a69c5364eff6b
parent 0a6a0bf18de14194c429e70adc682d221ac19f0c
Author: mpizzzle <m@michaelpercival.xyz>
Date:   Sun, 27 Sep 2020 22:11:22 +0100

looked up the proper algo for calculating divisors, massive time improvement

Diffstat:
MEuler_95.cpp | 44++++++++++++++------------------------------
1 file changed, 14 insertions(+), 30 deletions(-)

diff --git a/Euler_95.cpp b/Euler_95.cpp @@ -1,47 +1,32 @@ #include "Euler.h" -int sumProperDivisors(int n) -{ - int sum = 0; - - for(int k = 1; k <= n / 2; ++k) - { - if(n % k == 0) - { - sum += k; - } - } - - return sum; -} - int Euler::AmicableChains() { int one_million = 1000000; int longest = 0; int solution = 0; + double root = floor(sqrt(one_million)) + 1; - std::vector<int> cache(one_million + 1, 0); + std::vector<int> divisors(one_million + 1, 1); - for (int i = 0; i <= one_million; ++i) { - cache[i] = sumProperDivisors(i); - std::cout << i << std::endl; + for (int i = 2; i < root; ++i) { + for (int j = 2; i * j <= one_million; ++j) { + divisors[i * j] += i + ((j >= root) ? j : 0); + } } - std::cout << std::endl << "precalc done." << std::endl; + //std::cout << std::endl << "precalc done." << std::endl; for (int n = 1; n <= one_million; ++n) { int length = 0; int candidate = one_million; int slow_ptr = n; int fast_ptr = n; - std::cout << n << ": "; while(true) { - fast_ptr = cache[fast_ptr]; + fast_ptr = divisors[fast_ptr]; if (fast_ptr <= 1 || fast_ptr > one_million) { - std::cout << "no bueno." << std::endl; break; } @@ -49,7 +34,7 @@ int Euler::AmicableChains() while (true) { std::cout << slow_ptr << " -> "; length++; - fast_ptr = cache[fast_ptr]; + fast_ptr = divisors[fast_ptr]; if (slow_ptr < candidate) { candidate = slow_ptr; @@ -67,22 +52,21 @@ int Euler::AmicableChains() std::cout << "not a winner." << std::endl; } - cache[solution] = 0; + divisors[candidate] = 1; break; } - slow_ptr = cache[slow_ptr]; - fast_ptr = cache[fast_ptr]; + slow_ptr = divisors[slow_ptr]; + fast_ptr = divisors[fast_ptr]; } break; } - slow_ptr = cache[slow_ptr]; - fast_ptr = cache[fast_ptr]; + slow_ptr = divisors[slow_ptr]; + fast_ptr = divisors[fast_ptr]; if (fast_ptr <= 1 || slow_ptr > one_million || fast_ptr > one_million) { - std::cout << "no bueno." << std::endl; break; } }