Reputation: 13
Write a function getNumberOfSquares(int n) (C) / get_number_of_squares that will return how many integer (starting from 1, 2...) numbers raised to power of 2 and then summed up are less than some number given as a parameter.
e.g 1: For n = 6 result should be 2 because 1^2 + 2^2 = 1 + 4 = 5 and 5 < 6 E.g 2: For n = 15 result should be 3 because 1^2 + 2^2 + 3^2 = 1 + 4 + 9 = 14 and 14 < 15
For the function above I wrote a program but the test program gave an error that is when input is getNumberOfSquares(100000)
function should return 66 but mine returns 403.
Here is my solution:
int getNumberOfSquares(int n){
int sum=0;
int limit=0;
for (int i = 1; i < n && n>sum; ++i)
{
sum += i*i;
++limit;
if(sum>=n){
sum -= i*i;
--limit;
}
}
return limit;
}
Upvotes: 0
Views: 684
Reputation: 1573
You want to find the biggest i
such that sum < n
. So this should be the only condition breaking the loop. You don't need to check even that i < n
.
Now the problem of your code is that you modify sum
when it gets big enough to break the loop, making it again less than n
. So if sum < n
was your only condition you would have had an infinite loop. But since you have the i < n
condition, the program keep adding and subtracting i*i
to sum
until i < n
.
If n
is small enough, adding and subtracting i*i
doesn't change sum
and when the loop breaks you get your result.
But if i
can grow big enough to make sum greater than the greatest int
you can have, sum
overflows and becomes a meaningless value.
The solution is to eliminate the condition if(sum>=n){}
.
Removing the condition will reveal that limit
is like i
, so you can even use i
as returned value.
And keeping in mind that you don't need the condition i < n
, your function becomes
int getNumberOfSquares(int n) {
int i, sum = 0;
for(i = 1; sum < n; ++i) {
sum += i*i;
}
return i-2;
}
Returning i-2
because the i
making sum > n
was already 1 more than the value you wanted to return and then before sum > n
is checked, thefor
increments i
.
Upvotes: 0
Reputation: 223689
Assuming that an integer is 32 bits on your system, i*i
will overflow once it reaches a value of 65536. That causes the inaccuracies.
However it shouldn't actually reach that point, since you continue to check values of i
even after the value of sum
exceeds n
. You should break out of the loop when you reach that point.
int getNumberOfSquares(int n){
int sum=0;
int limit=0;
for (int i = 1; i < n; ++i)
{
if (sum + i*i >= n) {
return limit;
}
sum += i*i;
++limit;
}
return limit;
}
Upvotes: 1