How many numbers made out of N digits, have the sum S? (dynamic programming) - c

So I just can't undestand how you do this. You input like N=2 and S=3, which means how many numbers made out of 2 digits, have their sum =3? Like 12 => 1+2= 3; for N=2 and S=3 , there are 3 numbers: 12,30,21.
I don't really know dynamic programming too well. How are you supposed to think this algorithm and the ones like this one?

Just Think about a brute force / Backtrack solution. How would you write that, which states do you need and which states can be dropped?
For this particular problem what you can do is insert a digit at a position starting from the most significant digit and move on to the next position keeping track of the sum. After inserting all the digits, if the sum is zero then you increment your answer by 1.
So the Backtrack solution will be something like this
void f(int pos,int sum) {
if(pos == n) {
if(!sum) ans += 1;
return;
}
for(int i = 0 ; i < 10 ; i++)
f(pos + 1 , sum - i);
}
If you can come up with the backTrack solution then already 90% of your work is done. For dynamic programming, you just have to save the states so that you will not have to recalculate a state twice. Also, think about the corner cases and base cases. In our backTrack solution, we have a bug. We should not insert 0 at the most significant digits.
Fixing all of that The code should look something like this
#define maxN 1000
#define maxSum 1000
#define i64 long long int
#define mod 1000000007
int n;
i64 dp[maxN][maxSum];
i64 f(int pos,int sum) {
if(sum < 0) return 0;
if(pos == n)
{
if(!sum) return 1;
return 0;
}
if( dp[pos][sum] != -1)
return dp[pos][sum];
int lo = 0;
if(!pos)
lo = 1;
i64 ans = 0;
for(int i = lo ; i < 10 ; i++)
ans += f(pos + 1, sum - i);
ans %= mod;
return dp[pos][sum] = ans;
}
int main()
{
int s;
cin >> n >> s;
memset(dp,-1,sizeof dp);
cout << f(0,s) << endl;
return 0;
}
The time complexity of the code is O(maxN * maxSum * 10)
You can find a more optimized solution online. But Once you learn a bit more about dynamic programming, You will realize that coming up with a dp solution is much faster and easier than other solutions. Happy Coding.

Related

What is the time complexity of exponentiation by squaring?

Here is a code to exponentiate a number to a given power:
#include <stdio.h>
int foo(int m, int k) {
if (k == 0) {
return 1;
} else if (k % 2 != 0) {
return m * foo(m, k - 1);
} else {
int p = foo(m, k / 2);
return p * p;
}
}
int main() {
int m, k;
while (scanf("%d %d", &m, &k) == 2) {
printf("%d\n", foo(m, k));
}
return 0;
}
How do I calculate the time complexity of the function foo?
I have been able to deduce that if k is a power of 2, the time complexity is O(log k).
But I am finding it difficult to calculate for other values of k. Any help would be much appreciated.
How do I calculate the time complexity of the function foo()?
I have been able to deduce that if k is a power of 2, the time complexity is O(logk).
First, I assume that the time needed for each function call is constant (this would for example not be the case if the time needed for a multiplication depends on the numbers being multiplied - which is the case on some computers).
We also assume that k>=1 (otherwise, the function will run endlessly unless there is an overflow).
Let's think the value k as a binary number:
If the rightmost bit is 0 (k%2!=0 is false), the number is shifted right by one bit (foo(m,k/2)) and the function is called recursively.
If the rightmost bit is 1 (k%2!=0 is true), the bit is changed to a 0 (foo(m,k-1)) and the function is called recursively. (We don't look at the case k=1, yet.)
This means that the function is called once for each bit and it is called once for each 1 bit. Or, in other words: It is called once for each 0 bit in the number and twice for each 1 bit.
If N is the number of function calls, n1 is the number of 1 bits and n0 is the number of 0 bits, we get the following formula:
N = n0 + 2*n1 + C
The constant C (C=(-1), if I didn't make a mistake) represents the case k=1 that we ignored up to now.
This means:
N = (n0 + n1) + n1 + C
And - because n0 + n1 = floor(log2(k)) + 1:
floor(log2(k)) + C <= N <= 2*floor(log2(k)) + C
As you can see, the time complexity is always O(log(k))
O(log(k))
Some modification added to output a statistics for spread sheet plot.
#include <stdio.h>
#include <math.h>
#ifndef TEST_NUM
#define TEST_NUM (100)
#endif
static size_t iter_count;
int foo(int m, int k) {
iter_count++;
if (k == 0) {
return 1;
} else if(k == 1) {
return m;
} else if (k % 2 != 0) {
return m * foo(m, k - 1);
} else {
int p = foo(m, k / 2);
return p * p;
}
}
int main() {
for (int i = 1; i < TEST_NUM; ++i) {
iter_count = 0;
int dummy_result = foo(1, i);
printf("%d, %zu, %f\n", i, iter_count, log2(i));
}
return 0;
}
Build it.
gcc t1.c -DTEST_NUM=10000
./a > output.csv
Now open the output file with a spread sheet program and plot the last two output columns.
For k positive, the function foo calls itself recursively p times if k is the p-th power of 2. If k is not a power of 2, the number of recursive calls is strictly inferior to 2 * p where p is the exponent of the largest power of 2 inferior to k.
Here is a demonstration:
let's expand the recursive call in the case k % 2 != 0:
int foo(int m, int k) {
if (k == 1) {
return m;
} else
if (k % 2 != 0) { /* 2 recursive calls */
// return m * foo(m, k - 1);
int p = foo(m, k / 2);
return m * p * p;
} else { /* 1 recursive call */
int p = foo(m, k / 2);
return p * p;
}
}
The total number of calls is floor(log2(k)) + bitcount(k), and bitcount(k) is by construction <= ceil(log2(k)).
There are no loops in the code and the time of each individual call is bounded by a constant, hence the overall time complexity of O(log k).
The number of times the function is called (recursively or not) per power call is proportional to the minimum number of bits in the exponent required to represent it in binary form.
Each time you enter in the function, it solves by reducing the number by one if the exponent is odd, OR reducing it to half if the exponent is even. This means that we will do n squares per significant bit in the number, and m more multiplications by the base for all the bits that are 1 in the exponent (which are, at most, n, so m < n) for a 32bit significant exponent (this is an exponent between 2^31 and 2^32 the routine will do between 32 and 64 products to get the result, and will reenter to itself a maximum of 64 times)
as in both cases the routine is tail-recursive, the code you post can be substituted with an iterative code in which a while loop is used to solve the problem.
int foo(int m, int k)
{
int prod = 1; /* last recursion foo(m, 0); */
int sq = m; /* squares */
while (k) {
if (k & 1) {
prod *= sq; /* foo(m, k); k odd */
}
k >>= 1;
sq *= sq;
}
return prod; /* return final product */
}
That's huge savings!!! (between 32 multiplications and 64 multiplications, to elevate something to 1,000,000,000 power)

Read from the standard input a natural number, n. Find the greatest perfect square that is less than or equal to n

#include <stdio.h>
#include <stdlib.h>
int main() {
int i, j, n, maxi = 0;
printf("\n Introduce the number:\n");
scanf("%d", &n);
for (j = 1; j <= n; j++)
{
i = 0;
while (i < j) {
i++;
if (j == i * i) {
if (j > maxi) {
maxi = j;
printf("%d", maxi);
}
}
}
}
return 0;
}
I have to find the greatest perfect square smaller than than a number n, I succeeded in finding all the perfect squares that are smaller than the number n but because each time it finds a perfect square it displays it I couldn't think of any way to compare all the perfect square that were found (or at least that's what I think the problem is) so I would appreciate some help. I already know that you could also solve this problem using a more simpler method ( like the one below ) and if you have any other ideas on how to solve it I'd like to hear them.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n,j;
printf("\n Your number:\n");
scanf("%d",&n);
j=(int)sqrt(n);
printf("%d",j*j);
return 0;
}
You only need a single loop here. Check if i*i <= n. If so, set maxi to i*i and increment i:
int n, i = 1, sq = 1;
printf("\n Introduce the number:\n");
scanf("%d", &n);
while (i*i <= n) {
sq = i*i;
i++;
}
printf("sq=%d\n", sq);
Find the greatest perfect square that is less than or equal to n
For n>=0, this is akin to finding the integer square root of n.
unsigned greatest_perfect_square(unsigned x) {
unsigned root = usqrt(x);
return root * root;
}
if you have any other ideas on how to solve it I'd like to hear them.
The order of complexity to find the square root is O(bit-width-of-type-n). e.g. 16 iterations.
#include <limits.h>
unsigned usqrt(unsigned x) {
unsigned y = 0;
unsigned xShifted = 0;
const unsigned MSBit = UINT_MAX - UINT_MAX/2;
// This constant relies on no padding and bit width even
const unsigned TwoBitCount_N = sizeof(x) * CHAR_BIT / 2;
for (unsigned TwoBitCount = TwoBitCount_N; TwoBitCount > 0; TwoBitCount--) {
// Shift `xShifted` 2 places left while shifting in the 2 MSbits of x
xShifted <<= 1;
if (x & MSBit) {
xShifted |= 1;
}
x <<= 1;
xShifted <<= 1;
if (x & MSBit) {
xShifted |= 1;
}
x <<= 1;
// Shift the answer 1 bit left
y <<= 1;
// Form test value as y*2 + 1
unsigned Test = (y << 1) | 1;
// If xShifted big enough ...
if (xShifted >= Test) {
xShifted -= Test;
// Increment answer
y |= 1;
}
}
return y;
}
OP's method is far far slower. Even the inner loop takes O(sqrt(n)) time.
Note:
OP's code: j == i * i is subject to overflow and leads to the incorrect answer when j is larger.
j/i == i performs a like test without overflow.
#Jonathan Leffler suggested a Newton-Raphson approximation approach. Some lightly tested code below works quite fast, often taking only a few iterations.
I suspect this is O(log(bit-width-of-type-n)) for the main part, yet of course still O(log(bit-width-of-type-n)) for bit_width().
Both of the functions could be improved.
unsigned bit_width(unsigned x) {
unsigned width = 0;
while (x) {
x /= 2;
width++;
}
return width;
}
unsigned usqrt_NR(unsigned x) {
if (x == 0) {
return 0;
}
unsigned y = 1u << bit_width(x)/2;
unsigned y_previous;
unsigned diff;
unsigned diff1count = 0;;
do {
y_previous = y;
y = (y + x/y)/2;
diff = y_previous < y ? y - y_previous : y_previous - y;
if (diff == 1) diff1count++;
} while (diff > 1 || (diff == 1 && diff1count <= 1));
y = (y_previous + y)/2;
return y;
}
This minimizes the number of multiplications: it looks for the first square which is larger than n, meaning that the perfect square immediately before was the solution.
for (i = 1; i <= n; i++) {
if (i*i > n) {
break;
}
}
i--;
// i*i is your answer
On some platforms it might be useful to exploit the fact that (i+1)*(i+1) = i*i + 2*i + 1, or in other words, if you already have i^2, (i+1)^2 is obtained by adding i to it twice, and incrementing by 1; and at the beginning, 0^2 is 0 to prime the cycle.
for (i = 0, sq = 0; i < n; i++) {
sq += i; // Or on some platforms sq += i<<1 instead of two sums
sq += i; // Some compilers will auto-optimize "sq += 2*i" for the platform
sq++; // Or even sq += ((2*i)|1) as adding 1 to even numbers is OR'ing 1
if (sq > n) {
break;
}
// if sq is declared as signed integer, a possible overflow will
// show it as being negative. This way we can still get a "correct" result
// with i the smallest root that does not overflow.
// In 16-bit arithmetic this is 181, root of 32761; next square would be
// 33124 which cannot be represented in signed 16-bit space.
if (sq < 0) {
break;
}
}
// (i*i) is your answer

Unexpected error for recursive collatz implementation

EDIT: When I upload the code to the automatic testing platform the program doesn't crash there - it returns the correct result, but takes too long (exceeds 5 seconds)... wtf...
For university I have to implement a function that returns the number of steps taken from the input to reach 1, by following the collatz conjecture. The conjecture is very simple - given any integer number:
1. If it is even - divide it by two (n/2)
2. If it is odd - times it by 3 and add one (n*3+1)
The conjecture is that all numbers will eventually reach 1. We don't have to prove or check this, we just need to return the steps taken for a given number.
We have done this problem before, but this time we must check much larger numbers (they specify to use long instead of int) AND use recursion. They have given us skeleton code, and asked us to implement only the function - so all of my code is contained inside
int lengthCollatz(long n) { //mycode }
The skeleton code in the main collects two input values - a and b, where a < b <100000000. It checks how many steps it takes for each number between a and b, following the collatz sequence, to reach 1, and then returns the number with the highest amount of steps taken.
The function I added seems to work perfectly fine, but at larger values (when input 2 is in the millions) it seems to crash for no reason and gives no error. I've tried changing everything to unsigned longs and even long longs to see if something is overflowing - in that case the program just gets stuck... I don't understand what's wrong, please help me diagnose the error. P.S. How can I improve the speed of these calculations? We have a limit of 5 seconds.
All of my code is inside the lengthCollatz function (and the length global variable just above it) Can you identify the problem?
#include <stdio.h>
#define MAX64 9223372036854775807L /* 2ˆ63 -1 */
int length = 0;
int lengthCollatz(long n) {
length++;
//if not 1
if(n!=1){
//if odd
if(n&1) {
lengthCollatz(n=n*3+1);
}
//if even
else {
lengthCollatz(n/=2);
}
}
//if reached n = 1
else {
//return amount of steps taken
int returnLength = length;
length = 0;
return returnLength;
}
}
int main(int argc, char *argv[])
{
int n, a, b, len=-1;
scanf ("%d %d", &a, &b);
while (a <= b) {
int l = lengthCollatz(a);
if (l > len) {
n = a;
len = l;
}
a++;
}
printf("%d\n", n);
return 0;
}
Updated function:
int lengthCollatz(long n) {
if(n==1){
//return depthRecursion;
}
else {
if(n&1) {
n=n*3+1;
}
else {
n/=2;
}
return lengthCollatz(n);
}
}
Here's one alternative version which does not segfault for the input range given by OP:
int collatz(unsigned long n)
{
if (n == 1)
return 1;
else if (n & 1)
return 1 + collatz(n * 3 + 1);
else
return 1 + collatz(n >> 1);
}
AFAICT, it works OK, but it's very slow. 29 seconds on my mediocre PC. An optimized version runs two seconds faster by not calling itself when the result can be precomputed, but that version borders on manual loop unrolling. FWIW:
int collatz(unsigned long n)
{
if (n == 1)
return 1;
if (n & 1)
return 2 + collatz((n * 3 + 1) >> 1);
// Is n dividable by 16?
if (n & 0xF == 0)
return 4 + collatz(n >> 4);
// Is n dividable by 8?
if (n & 0x7 == 0)
return 3 + collatz(n >> 3);
// Is n dividable by 4?
if (n & 0x3 == 0)
return 2 + collatz(n >> 2);
return 1 + collatz(n >> 1);
}
There are of course other ways to solve this, but to finish in five seconds? Please post the solution if you find one.

Faster algorithm to find how many numbers are not divisible by a given set of numbers

I am trying to solve an online judge problem: http://opc.iarcs.org.in/index.php/problems/LEAFEAT
The problem in short:
If we are given an integer L and a set of N integers s1,s2,s3..sN, we have to find how many numbers there are from 0 to L-1 which are not divisible by any of the 'si's.
For example, if we are given, L = 20 and S = {3,2,5} then there are 6 numbers from 0 to 19 which are not divisible by 3,2 or 5.
L <= 1000000000 and N <= 20.
I used the Inclusion-Exclusion principle to solve this problem:
/*Let 'T' be the number of integers that are divisible by any of the 'si's in the
given range*/
for i in range 1 to N
for all subsets A of length i
if i is odd then:
T += 1 + (L-1)/lcm(all the elements of A)
else
T -= 1 + (L-1)/lcm(all the elements of A)
return T
Here is my code to solve this problem
#include <stdio.h>
int N;
long long int L;
int C[30];
typedef struct{int i, key;}subset_e;
subset_e A[30];
int k;
int gcd(a,b){
int t;
while(b != 0){
t = a%b;
a = b;
b = t;
}
return a;
}
long long int lcm(int a, int b){
return (a*b)/gcd(a,b);
}
long long int getlcm(int n){
if(n == 1){
return A[0].key;
}
int i;
long long int rlcm = lcm(A[0].key,A[1].key);
for(i = 2;i < n; i++){
rlcm = lcm(rlcm,A[i].key);
}
return rlcm;
}
int next_subset(int n){
if(k == n-1 && A[k].i == N-1){
if(k == 0){
return 0;
}
k--;
}
while(k < n-1 && A[k].i == A[k+1].i-1){
if(k <= 0){
return 0;
}
k--;
}
A[k].key = C[A[k].i+1];
A[k].i++;
return 1;
}
int main(){
int i,j,add;
long long int sum = 0,g,temp;
scanf("%lld%d",&L,&N);
for(i = 0;i < N; i++){
scanf("%d",&C[i]);
}
for(i = 1; i <= N; i++){
add = i%2;
for(j = 0;j < i; j++){
A[j].key = C[j];
A[j].i = j;
}
temp = getlcm(i);
g = 1 + (L-1)/temp;
if(add){
sum += g;
} else {
sum -= g;
}
k = i-1;
while(next_subset(i)){
temp = getlcm(i);
g = 1 + (L-1)/temp;
if(add){
sum += g;
} else {
sum -= g;
}
}
}
printf("%lld",L-sum);
return 0;
}
The next_subset(n) generates the next subset of size n in the array A, if there is no subset it returns 0 otherwise it returns 1. It is based on the algorithm described by the accepted answer in this stackoverflow question.
The lcm(a,b) function returns the lcm of a and b.
The get_lcm(n) function returns the lcm of all the elements in A.
It uses the property : LCM(a,b,c) = LCM(LCM(a,b),c)
When I submit the problem on the judge it gives my a 'Time Limit Exceeded'. If we solve this using brute force we get only 50% of the marks.
As there can be upto 2^20 subsets my algorithm might be slow, hence I need a better algorithm to solve this problem.
EDIT:
After editing my code and changing the function to the Euclidean algorithm, I am getting a wrong answer, but my code runs within the time limit. It gives me a correct answer to the example test but not to any other test cases; here is a link to ideone where I ran my code, the first output is correct but the second is not.
Is my approach to this problem correct? If it is then I have made a mistake in my code, and I'll find it; otherwise can anyone please explain what is wrong?
You could also try changing your lcm function to use the Euclidean algorithm.
int gcd(int a, int b) {
int t;
while (b != 0) {
t = b;
b = a % t;
a = t;
}
return a;
}
int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}
At least with Python, the speed differences between the two are pretty large:
>>> %timeit lcm1(103, 2013)
100000 loops, best of 3: 9.21 us per loop
>>> %timeit lcm2(103, 2013)
1000000 loops, best of 3: 1.02 us per loop
Typically, the lowest common multiple of a subset of k of the s_i will exceed L for k much smaller than 20. So you need to stop early.
Probably, just inserting
if (temp >= L) {
break;
}
after
while(next_subset(i)){
temp = getlcm(i);
will be sufficient.
Also, shortcut if there are any 1s among the s_i, all numbers are divisible by 1.
I think the following will be faster:
unsigned gcd(unsigned a, unsigned b) {
unsigned r;
while(b) {
r = a%b;
a = b;
b = r;
}
return a;
}
unsigned recur(unsigned *arr, unsigned len, unsigned idx, unsigned cumul, unsigned bound) {
if (idx >= len || bound == 0) {
return bound;
}
unsigned i, g, s = arr[idx], result;
g = s/gcd(cumul,s);
result = bound/g;
for(i = idx+1; i < len; ++i) {
result -= recur(arr, len, i, cumul*g, bound/g);
}
return result;
}
unsigned inex(unsigned *arr, unsigned len, unsigned bound) {
unsigned i, result = bound, t;
for(i = 0; i < len; ++i) {
result -= recur(arr, len, i, 1, bound);
}
return result;
}
call it with
unsigned S[N] = {...};
inex(S, N, L-1);
You need not add the 1 for the 0 anywhere, since 0 is divisible by all numbers, compute the count of numbers 1 <= k < L which are not divisible by any s_i.
Create an array of flags with L entries. Then mark each touched leaf:
for(each size in list of sizes) {
length = 0;
while(length < L) {
array[length] = TOUCHED;
length += size;
}
}
Then find the untouched leaves:
for(length = 0; length < L; length++) {
if(array[length] != TOUCHED) { /* Untouched leaf! */ }
}
Note that there is no multiplication and no division involved; but you will need up to about 1 GiB of RAM. If RAM is a problem the you can use an array of bits (max. 120 MiB).
This is only a beginning though, as there are repeating patterns that can be copied instead of generated. The first pattern is from 0 to S1*S2, the next is from 0 to S1*S2*S3, the next is from 0 to S1*S2*S3*S4, etc.
Basically, you can set all values touched by S1 and then S2 from 0 to S1*S2; then copy the pattern from 0 to S1*S2 until you get to S1*S2*S3 and set all the S3's between S3 and S1*S2*S3; then copy that pattern until you get to S1*S2*S3*S4 and set all the S4's between S4 and S1*S2*S3*S4 and so on.
Next; if S1*S2*...Sn is smaller than L, you know the pattern will repeat and can generate the results for lengths from S1*S2*...Sn to L from the pattern. In this case the size of the array only needs to be S1*S2*...Sn and doesn't need to be L.
Finally, if S1*S2*...Sn is larger than L; then you could generate the pattern for S1*S2*...(Sn-1) and use that pattern to create the results from S1*S2*...(Sn-1) to S1*S2*...Sn. In this case if S1*S2*...(Sn-1) is smaller than L then the array doesn't need to be as large as L.
I'm afraid your problem understanding is maybe not correct.
You have L. You have a set S of K elements. You must count the sum of quotient of L / Si. For L = 20, K = 1, S = { 5 }, the answer is simply 16 (20 - 20 / 5). But K > 1, so you must consider the common multiples also.
Why loop through a list of subsets? It doesn't involve subset calculation, only division and multiple.
You have K distinct integers. Each number could be a prime number. You must consider common multiples. That's all.
EDIT
L = 20 and S = {3,2,5}
Leaves could be eaten by 3 = 6
Leaves could be eaten by 2 = 10
Leaves could be eaten by 5 = 4
Common multiples of S, less than L, not in S = 6, 10, 15
Actually eaten leaves = 20/3 + 20/2 + 20/5 - 20/6 - 20/10 - 20/15 = 6
You can keep track of the distance until then next touched leaf for each size. The distance to the next touched leaf will be whichever distance happens to be smallest, and you'd subtract this distance from all the others (and wrap whenever the distance is zero).
For example:
int sizes[4] = {2, 5, 7, 9};
int distances[4];
int currentLength = 0;
for(size = 0 to 3) {
distances[size] = sizes[size];
}
while(currentLength < L) {
smallest = INT_MAX;
for(size = 0 to 3) {
if(distances[size] < smallest) smallest = distances[size];
}
for(size = 0 to 3) {
distances[size] -= smallest;
if(distances[size] == 0) distances[size] = sizes[size];
}
while( (smallest > 1) && (currentLength < L) ) {
currentLength++;
printf("%d\n", currentLength;
smallest--;
}
}
#A.06: u r the one with username linkinmew on opc, rite?
Anyways, the answer just requires u to make all possible subsets, and then apply inclusion exclusion principle. This will fall well within the time bounds for the data given. For making all possible subsets, u can easily define a recursive function.
i don't know about programming but in math there is a single theorem which works on a set that has GCD 1
L=20, S=(3,2,5)
(1-1/p)(1-1/q)(1-1/r).....and so on
(1-1/3)(1-1/2)(1-1/5)=(2/3)(1/2)(4/5)=4/15
4/15 means there are 4 numbers in each set of 15 number which are not divisible by any number rest of it can be count manually eg.
16, 17, 18, 19, 20 (only 17 and 19 means there are only 2 numbers thatr can't be divided by any S)
4+2=6
6/20 means there are only 6 numbers in first 20 numbers that can't be divided by any s

Combinations based on 2 variables

What I'm trying to accomplish is making a function to the following:
Imagine that I have between 1-9 squares. Those squares have a number assigned to them globally, not individually. They are like a set, and that set has this number.
E.g.: | _ | _ | _ | 19
What I'm trying to do is a function that gives me the possible combinations depending on number of squares and the number associated with them. For the example above: 9, 8, 2 is one of the possible combinations. However I just want the numbers that are in those combinations, not the combinations themselves. Plus they have to be unique (shouldn't be 9, 9, 1). Oh and those numbers range from 1-9 only.
How can I achieve this in C? If you are wondering this is for a puzzle game.
Thanks in advance!
Looks like you are trying to find a restricted Partition of the integer on the right. The link should give you a good starting place, and you should be able to find some algorithms that generate partitions of an integer into an arbitrary number of parts.
For future reference, in combinatorics we say "order doesn't matter" to mean "I only want the set of numbers, not a specific ordering"
//Sets the given digit array to contain the "first" set of numbers which sum to sum
void firstCombination(int digits[], int numDigits, int sum) {
reset(digits, 0, 1, numDigits, sum);
}
//Modifies the digit array to contain the "next" set of numbers with the same sum.
//Returns false when no more combinations left
int nextCombination(int digits[], int numDigits) {
int i;
int foundDiffering = 0;
int remaining = 0;
for (i = numDigits - 1; i > 0; i--) {
remaining += digits[i];
if (digits[i] - digits[i - 1] > 1) {
if (foundDiffering || digits[i] - digits[i - 1] > 2) {
digits[i - 1]++;
remaining--;
break;
} else
foundDiffering = 1;
}
}
if (i == 0)
return 0;
else {
reset(digits, i, digits[i - 1] + 1, numDigits - i, remaining);
return 1;
}
}
//Helper method for firstCombination and nextCombination
void reset(int digits[], int off, int lowestValue, int numDigits, int sum) {
int i;
int remaining = sum;
for (i = 0; i < numDigits; i++) {
digits[i + off] = lowestValue;
remaining -= lowestValue;
lowestValue++;
}
int currentDigit = 9;
for (i = numDigits + off - 1; i >= off; i--) {
if (remaining >= currentDigit - digits[i]) {
remaining -= currentDigit - digits[i];
digits[i] = currentDigit;
currentDigit--;
} else {
digits[i] += remaining;
break;
}
}
}
It sounds like what you're working on is very similar to kakuro, also know as Cross Sums: http://en.wikipedia.org/wiki/Cross_Sums
There are generators out there for these kinds of puzzles, for example: http://www.perlmonks.org/?node_id=550884
I suspect that most kakuro generators would have to solve your exact problem, so you might look at some for inspiration.

Resources