Search code examples
cfactorial

Factorial as a sum of consecutive number


I was recently solving a problem "No. of ways to express factorial of a number as sum of consecutive number" My solution is :

int fact_as_sum(int n) {  // n is the number whose factorial need to be taken
    long int fact=1;
    int temp=0,count=0;

    for(int i=n;i>0;i--){
        fact*=i;
    }

    printf("%d\n",fact);
    for(int i=fact/2;i>0;i--) {
        int j=i;
        temp=fact;
        while(temp>=0) {
            if(temp==0) {
                count++;
                break;
            }
            else
                temp-=j;
            j--;
        }
    }

    return count;    
}

The solution works correct till small no. of 10!.

But my solution has high complexity. Can anyone suggest a less complex solution ?

Thanks


Solution

  • Ok, so this problem tickled my brain a lot, so first of all thank you for that, I love to solve these kind of problems! I started with a math analysis of the problem in order to find the best implementation, and I came up with this solution:

    By defining n as the factorial result number, m the number of sums to be performed and x the starting number for the addition, it all breaks down to the following formula:

    first formula.

    This can now be simplified, resulting in the following formula:

    enter image description here.

    That can be also simplified, giving the following result:

    enter image description here.

    Solving for x (the starting number for addition), results in:

    enter image description here.

    It is now possible to iterate for all the values of m to find the wanted x value. the lower bound for m is for sure 0, it is not possible to add a negative quantity of numbers! The top bound can be found by noticing that x should be a positive number, it would have no sense to consider negative values that will be nulled by the corresponding positive part! This gives the following result:

    enter image description here

    That yields the following result:

    enter image description here

    The negative value of m is discarded as previously said.

    This translates in the following C code:

    #include <stdio.h>
    #include <math.h>
    
    void main() {
        int fact = 8;  //select the wanted factorial to compute
        float n = 1;
        int i;
        float x;
        float m;
    
        printf("calculating %d factorial...\n", fact);
    
        for (i = 2; i < fact + 1; i++) {
            n *= (float)i;
        }
    
        printf("the factorial result is %d\n", (int)n);
        printf("calculating the sum of consecutive numbers...\n");
    
        //compute the maximum number of iterations
        int maxIter = (int)((-1 + sqrt(1 + 8 * n)) / 2);
    
        for (i = 0; i < maxIter; i++) {
            m = (float)i;
            //apply the formula
            x = (n / (m + 1)) - (m / 2);
            if (x - (float)((int)x) == 0) {
                printf("found a correct sum!\n");
                printf("the starting number is: %d\n", (int)x);
                printf("the number of sums is: %d\n", i + 1);
            }
        }
    }
    

    I've tried this solution on a couple of values and wrote the code for the test, the results seem right. There is an issue with the factorial though, since the factorial reaches very high values quickly, memory needs to be managed better.

    Hope I gave an interesting solution, I had fun solving it!

    Please correct in case there are problems with this solution.