These numbers are called Polite Numbers.
And, conveniently, the only numbers that aren't polite are the powers of 2.
So, that gives us 2 options. We can either determine that a number is polite, OR we can determine that it is not a power of 2.
I did both; the latter is easier (and more efficient).
This determines whether or not a number is polite:
boolean IsSumOfConsecutiveInts(int num)
{
int sumOfFirstIIntegers = 3;
for (int i = 2; sumOfFirstIIntegers <= num; i++)
{
if (i%2 == 0 ? (num%i == i/2) : (num%i == 0))
{
return true;
}
sumOfFirstIIntegers += i + 1;
}
return false;
}
This one is pretty hard to understand. It took me a while to come up with.
Basically, i is the number of consecutive integers that we are checking;
sumOfFirstIIntegers is equal to the sum of the first i integers, so that means that all the numbers that can be expressed as a sum of i consecutive integers are greater than or equal to sumOfFirstIIntegers.
The last part that deserves discussing is the boolean statement i%2 == 0 ? (num%i == i/2) : (num%i == 0). Let's look at some examples:
i all sums of i consecutive positive integers
2 3, 5, 7, 9...
3 6, 9, 12, 15...
4 10, 14, 18, 22...
5 15, 20, 25, 30...
There are two cases, but in either case, we can express all possible numbers that are a sum of i consecutive integers pretty simply.
When i is even, num must be equal to (i * n) + (i / 2) where n is a non-negative integer. This can of course be written as num % i == i / 2.
When i is odd, num must be equal to i * n, where n is a non-negative integer. Which gives us our second condition num % i == 0.
In addition to these conditions, num can not be less than the sum of the first i positive integers. Hence, our for loop's conditional: sumOfFirstIIntegers <= num.
This determines whether a number is not a power of 2:
boolean IsSumOfConsecutiveInts(int num)
{
return (num & (num - 1)) != 0;
}
This answer does a good job of explaining why this works.
Note that both of the above solutions have the same result, they are just different ways of thinking about the problem.