As an alternative to manipulating the digits separately, as is done in the recursive solutions and the ones that use a Vector<>, you can rely on machine representations and arithmetic. This is no faster if you need to examine each digit each time through the loop, but if you're implementing an iterator then it will reduce your storage space within the iterator, and if you're not using every single value then it may also improve your efficiency. In any case, it's an interesting equivalent approach. Here goes...
First think about the slightly more general case where you have n
nested loops, each of which counts from 0 to num
. In that case, you are essentially just counting from 0 to num^n - 1
in base num. So you can do something like this:
for( int x=0; x<(num^n); x++ )
{
int digit_0 = x % num;
int digit_1 = (x/num) % num;
int digit_2 = (x/num^2) % num;
// etc.
}
Note that:
- If no native integer type is large enough for your application, then you will have to use some kind of large integer class. This will reduce the efficiency of the storage and increment parts, though maybe not as much as using a vector of length num.
- If you really do look at each digit each time, then you need a vector of digits, and you have not gained anything. This is really most useful when you're not looking at all the digits each time.
- All the divisors should be precomputed, so you do need to keep around a vector for that!
Anyway, for your particular question, you didn't want to count to num
each time, you wanted to count to num - (the sum of the already decided digits)
. The simplest way to account for this simply by putting an appropriate continue
condition into your loops. Here is is with some values substituted in for when n=2
and num=10
:
for( x=0; x<100; x++ ) // i.e. x < num*num
{
int ones = x%10; // i.e. x % num
int tens = (x/10) % 10; // i.e. (x/num) % num
if( ones + tens < 10 )
{
// actually do work
}
}
(In case it's not obvious, I don't mean you should actually use 100 and 10 in the code, this is just an illustrative example.)
You can make this more efficient by computing how much to increment x by, or by reducing the range of x and then mapping directly to your subspace instead of to the entire space. (But in 2-d and 3-d you are using exactly half the possible values, so that extra work would only get you a speedup of 2. I think it's the same when n>3, but I am too lazy to figure it out right now, sorry!)