Project Euler #211: Divisor Square Sum
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
1
down vote
favorite
I started doing hackerrank problems only recently and here's my attempt to solve this problem.
Basically, you're given two integers N
and K
, so you need to find the sum of all 1 <= n <= N
such that the sum is at most K
away from a perfect square.
For example, for N = 65
and K = 0
, we calculate the sum of squares of factors for all numbers from 1
to 65
, i.e. 1, 5, 10, ...
and see which of these sums is a perfect square (or more precisely 0
away from a perfect square). For 65
, that happens to be 1
and 42
, so the answer would be 43
.
#include <cmath>
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
// Lookup table
unordered_map<uint_fast16_t, uint_fast16_t> fac_sq_diff;
auto sum_fac_sq(uint_fast16_t n)
uint_fast16_t sum = 0;
// Calculate factors in pairs,
// eg. 20 => (1, 20), (2, 10), (4, 5)
auto sqrtn = sqrt(n);
for (auto i = 1; i <= sqrtn; ++i)
if (n % i == 0)
sum += (i * i);
auto j = n / i;
if (i != j)
sum += (j * j);
return sum;
uint_fast32_t solve(uint_fast16_t n, uint_fast16_t k)
uint_fast32_t result = 0;
int_fast32_t diff = 0;
for (uint_fast16_t j = 1; j <= n; ++j)
auto idiff = fac_sq_diff.find(j);
if (idiff == fac_sq_diff.end())
auto sum = sum_fac_sq(j);
// Closest perfect square:
// https://stackoverflow.com/questions/6054909
auto sqrtsum = static_cast<uint_fast16_t>(sqrt(static_cast<float>(sum)) + .5f);
diff = sum - (sqrtsum * sqrtsum);
diff = abs(diff);
idiff = fac_sq_diff.emplace(j, diff).first;
if (idiff->second <= k)
result += j;
return result;
int main()
// Expected input:
// 11
// 65 0
// 269 1
// 312 2
// 745 3
// 1457 4
uint_fast16_t q = 1;
cin >> q;
// Find max N and reserve lookup table mem
vector<pair<uint_fast16_t, uint_fast16_t>> NK;
uint_fast16_t max_N = 0;
for (auto i = 0; i < q; ++i)
uint_fast16_t N = 0, K = 0;
cin >> N >> K;
NK.emplace_back(N, K);
max_N = max(N, max_N);
fac_sq_diff.reserve(max_N);
for (auto &nk: NK)
cout << solve(nk.first, nk.second) << endl;
return 0;
No matter what I try, I am not able to get past the first test (in terms of speed). :(
I also tried the geometric summation formula to calculate the sum of factors squared, but my implementation turned out to be slower than this one.
c++ algorithm programming-challenge time-limit-exceeded c++14
add a comment |Â
up vote
1
down vote
favorite
I started doing hackerrank problems only recently and here's my attempt to solve this problem.
Basically, you're given two integers N
and K
, so you need to find the sum of all 1 <= n <= N
such that the sum is at most K
away from a perfect square.
For example, for N = 65
and K = 0
, we calculate the sum of squares of factors for all numbers from 1
to 65
, i.e. 1, 5, 10, ...
and see which of these sums is a perfect square (or more precisely 0
away from a perfect square). For 65
, that happens to be 1
and 42
, so the answer would be 43
.
#include <cmath>
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
// Lookup table
unordered_map<uint_fast16_t, uint_fast16_t> fac_sq_diff;
auto sum_fac_sq(uint_fast16_t n)
uint_fast16_t sum = 0;
// Calculate factors in pairs,
// eg. 20 => (1, 20), (2, 10), (4, 5)
auto sqrtn = sqrt(n);
for (auto i = 1; i <= sqrtn; ++i)
if (n % i == 0)
sum += (i * i);
auto j = n / i;
if (i != j)
sum += (j * j);
return sum;
uint_fast32_t solve(uint_fast16_t n, uint_fast16_t k)
uint_fast32_t result = 0;
int_fast32_t diff = 0;
for (uint_fast16_t j = 1; j <= n; ++j)
auto idiff = fac_sq_diff.find(j);
if (idiff == fac_sq_diff.end())
auto sum = sum_fac_sq(j);
// Closest perfect square:
// https://stackoverflow.com/questions/6054909
auto sqrtsum = static_cast<uint_fast16_t>(sqrt(static_cast<float>(sum)) + .5f);
diff = sum - (sqrtsum * sqrtsum);
diff = abs(diff);
idiff = fac_sq_diff.emplace(j, diff).first;
if (idiff->second <= k)
result += j;
return result;
int main()
// Expected input:
// 11
// 65 0
// 269 1
// 312 2
// 745 3
// 1457 4
uint_fast16_t q = 1;
cin >> q;
// Find max N and reserve lookup table mem
vector<pair<uint_fast16_t, uint_fast16_t>> NK;
uint_fast16_t max_N = 0;
for (auto i = 0; i < q; ++i)
uint_fast16_t N = 0, K = 0;
cin >> N >> K;
NK.emplace_back(N, K);
max_N = max(N, max_N);
fac_sq_diff.reserve(max_N);
for (auto &nk: NK)
cout << solve(nk.first, nk.second) << endl;
return 0;
No matter what I try, I am not able to get past the first test (in terms of speed). :(
I also tried the geometric summation formula to calculate the sum of factors squared, but my implementation turned out to be slower than this one.
c++ algorithm programming-challenge time-limit-exceeded c++14
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I started doing hackerrank problems only recently and here's my attempt to solve this problem.
Basically, you're given two integers N
and K
, so you need to find the sum of all 1 <= n <= N
such that the sum is at most K
away from a perfect square.
For example, for N = 65
and K = 0
, we calculate the sum of squares of factors for all numbers from 1
to 65
, i.e. 1, 5, 10, ...
and see which of these sums is a perfect square (or more precisely 0
away from a perfect square). For 65
, that happens to be 1
and 42
, so the answer would be 43
.
#include <cmath>
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
// Lookup table
unordered_map<uint_fast16_t, uint_fast16_t> fac_sq_diff;
auto sum_fac_sq(uint_fast16_t n)
uint_fast16_t sum = 0;
// Calculate factors in pairs,
// eg. 20 => (1, 20), (2, 10), (4, 5)
auto sqrtn = sqrt(n);
for (auto i = 1; i <= sqrtn; ++i)
if (n % i == 0)
sum += (i * i);
auto j = n / i;
if (i != j)
sum += (j * j);
return sum;
uint_fast32_t solve(uint_fast16_t n, uint_fast16_t k)
uint_fast32_t result = 0;
int_fast32_t diff = 0;
for (uint_fast16_t j = 1; j <= n; ++j)
auto idiff = fac_sq_diff.find(j);
if (idiff == fac_sq_diff.end())
auto sum = sum_fac_sq(j);
// Closest perfect square:
// https://stackoverflow.com/questions/6054909
auto sqrtsum = static_cast<uint_fast16_t>(sqrt(static_cast<float>(sum)) + .5f);
diff = sum - (sqrtsum * sqrtsum);
diff = abs(diff);
idiff = fac_sq_diff.emplace(j, diff).first;
if (idiff->second <= k)
result += j;
return result;
int main()
// Expected input:
// 11
// 65 0
// 269 1
// 312 2
// 745 3
// 1457 4
uint_fast16_t q = 1;
cin >> q;
// Find max N and reserve lookup table mem
vector<pair<uint_fast16_t, uint_fast16_t>> NK;
uint_fast16_t max_N = 0;
for (auto i = 0; i < q; ++i)
uint_fast16_t N = 0, K = 0;
cin >> N >> K;
NK.emplace_back(N, K);
max_N = max(N, max_N);
fac_sq_diff.reserve(max_N);
for (auto &nk: NK)
cout << solve(nk.first, nk.second) << endl;
return 0;
No matter what I try, I am not able to get past the first test (in terms of speed). :(
I also tried the geometric summation formula to calculate the sum of factors squared, but my implementation turned out to be slower than this one.
c++ algorithm programming-challenge time-limit-exceeded c++14
I started doing hackerrank problems only recently and here's my attempt to solve this problem.
Basically, you're given two integers N
and K
, so you need to find the sum of all 1 <= n <= N
such that the sum is at most K
away from a perfect square.
For example, for N = 65
and K = 0
, we calculate the sum of squares of factors for all numbers from 1
to 65
, i.e. 1, 5, 10, ...
and see which of these sums is a perfect square (or more precisely 0
away from a perfect square). For 65
, that happens to be 1
and 42
, so the answer would be 43
.
#include <cmath>
#include <vector>
#include <unordered_map>
#include <iostream>
using namespace std;
// Lookup table
unordered_map<uint_fast16_t, uint_fast16_t> fac_sq_diff;
auto sum_fac_sq(uint_fast16_t n)
uint_fast16_t sum = 0;
// Calculate factors in pairs,
// eg. 20 => (1, 20), (2, 10), (4, 5)
auto sqrtn = sqrt(n);
for (auto i = 1; i <= sqrtn; ++i)
if (n % i == 0)
sum += (i * i);
auto j = n / i;
if (i != j)
sum += (j * j);
return sum;
uint_fast32_t solve(uint_fast16_t n, uint_fast16_t k)
uint_fast32_t result = 0;
int_fast32_t diff = 0;
for (uint_fast16_t j = 1; j <= n; ++j)
auto idiff = fac_sq_diff.find(j);
if (idiff == fac_sq_diff.end())
auto sum = sum_fac_sq(j);
// Closest perfect square:
// https://stackoverflow.com/questions/6054909
auto sqrtsum = static_cast<uint_fast16_t>(sqrt(static_cast<float>(sum)) + .5f);
diff = sum - (sqrtsum * sqrtsum);
diff = abs(diff);
idiff = fac_sq_diff.emplace(j, diff).first;
if (idiff->second <= k)
result += j;
return result;
int main()
// Expected input:
// 11
// 65 0
// 269 1
// 312 2
// 745 3
// 1457 4
uint_fast16_t q = 1;
cin >> q;
// Find max N and reserve lookup table mem
vector<pair<uint_fast16_t, uint_fast16_t>> NK;
uint_fast16_t max_N = 0;
for (auto i = 0; i < q; ++i)
uint_fast16_t N = 0, K = 0;
cin >> N >> K;
NK.emplace_back(N, K);
max_N = max(N, max_N);
fac_sq_diff.reserve(max_N);
for (auto &nk: NK)
cout << solve(nk.first, nk.second) << endl;
return 0;
No matter what I try, I am not able to get past the first test (in terms of speed). :(
I also tried the geometric summation formula to calculate the sum of factors squared, but my implementation turned out to be slower than this one.
c++ algorithm programming-challenge time-limit-exceeded c++14
edited Jul 13 at 19:06
asked Jul 13 at 17:47
user3490458
21016
21016
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
5
down vote
accepted
As always, before tackling the Project Euler problems, do your math homework. Few hints:
Do not brute force. $sigma_2(n)$ is multiplicative. That allows it to be computed in a much more efficient way.
Do not throw away your work. $sigma_2(n)$ does not depend on $k$. Tabulate it once toward the maximal possible $N$, or extend it as $N$ grows.
Besides that, the constraints say $1 < N < 6cdot 10^6, 0 < K < 10^6$. uint_16
is surely insufficient.
+1 especially for reviewing the code and algorithm without revealing a complete solution and leaving the fun of discovery intact.
â Edward
Jul 13 at 20:46
Very helpful information, particularly regarding the multiplicative function. I think I'm back on track, thanks to you.
â user3490458
Jul 14 at 10:12
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
5
down vote
accepted
As always, before tackling the Project Euler problems, do your math homework. Few hints:
Do not brute force. $sigma_2(n)$ is multiplicative. That allows it to be computed in a much more efficient way.
Do not throw away your work. $sigma_2(n)$ does not depend on $k$. Tabulate it once toward the maximal possible $N$, or extend it as $N$ grows.
Besides that, the constraints say $1 < N < 6cdot 10^6, 0 < K < 10^6$. uint_16
is surely insufficient.
+1 especially for reviewing the code and algorithm without revealing a complete solution and leaving the fun of discovery intact.
â Edward
Jul 13 at 20:46
Very helpful information, particularly regarding the multiplicative function. I think I'm back on track, thanks to you.
â user3490458
Jul 14 at 10:12
add a comment |Â
up vote
5
down vote
accepted
As always, before tackling the Project Euler problems, do your math homework. Few hints:
Do not brute force. $sigma_2(n)$ is multiplicative. That allows it to be computed in a much more efficient way.
Do not throw away your work. $sigma_2(n)$ does not depend on $k$. Tabulate it once toward the maximal possible $N$, or extend it as $N$ grows.
Besides that, the constraints say $1 < N < 6cdot 10^6, 0 < K < 10^6$. uint_16
is surely insufficient.
+1 especially for reviewing the code and algorithm without revealing a complete solution and leaving the fun of discovery intact.
â Edward
Jul 13 at 20:46
Very helpful information, particularly regarding the multiplicative function. I think I'm back on track, thanks to you.
â user3490458
Jul 14 at 10:12
add a comment |Â
up vote
5
down vote
accepted
up vote
5
down vote
accepted
As always, before tackling the Project Euler problems, do your math homework. Few hints:
Do not brute force. $sigma_2(n)$ is multiplicative. That allows it to be computed in a much more efficient way.
Do not throw away your work. $sigma_2(n)$ does not depend on $k$. Tabulate it once toward the maximal possible $N$, or extend it as $N$ grows.
Besides that, the constraints say $1 < N < 6cdot 10^6, 0 < K < 10^6$. uint_16
is surely insufficient.
As always, before tackling the Project Euler problems, do your math homework. Few hints:
Do not brute force. $sigma_2(n)$ is multiplicative. That allows it to be computed in a much more efficient way.
Do not throw away your work. $sigma_2(n)$ does not depend on $k$. Tabulate it once toward the maximal possible $N$, or extend it as $N$ grows.
Besides that, the constraints say $1 < N < 6cdot 10^6, 0 < K < 10^6$. uint_16
is surely insufficient.
answered Jul 13 at 19:11
vnp
36.3k12890
36.3k12890
+1 especially for reviewing the code and algorithm without revealing a complete solution and leaving the fun of discovery intact.
â Edward
Jul 13 at 20:46
Very helpful information, particularly regarding the multiplicative function. I think I'm back on track, thanks to you.
â user3490458
Jul 14 at 10:12
add a comment |Â
+1 especially for reviewing the code and algorithm without revealing a complete solution and leaving the fun of discovery intact.
â Edward
Jul 13 at 20:46
Very helpful information, particularly regarding the multiplicative function. I think I'm back on track, thanks to you.
â user3490458
Jul 14 at 10:12
+1 especially for reviewing the code and algorithm without revealing a complete solution and leaving the fun of discovery intact.
â Edward
Jul 13 at 20:46
+1 especially for reviewing the code and algorithm without revealing a complete solution and leaving the fun of discovery intact.
â Edward
Jul 13 at 20:46
Very helpful information, particularly regarding the multiplicative function. I think I'm back on track, thanks to you.
â user3490458
Jul 14 at 10:12
Very helpful information, particularly regarding the multiplicative function. I think I'm back on track, thanks to you.
â user3490458
Jul 14 at 10:12
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f198443%2fproject-euler-211-divisor-square-sum%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password