N Factorial

Finding the factorial of any number n

Factorial of n (n!) = n * (n-1) * (n-2) * ..... * 3 * 2 * 1

The value of 100 factorial has 158 digits and 1000 factorial has 2568 digits, so I have utilized long multiplication and handling of digits in a dynamic list. The algorithm is pretty straight forward where the code is just utilizing my long multiplication algorithm.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/*
FACTORIAL DIGIT SUM

n! means n × (n − 1) × ... × 3 × 2 × 1

For example, 10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800,
and the sum of the digits in the number 10! is 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27.

Find the sum of the digits in the number 100!

*/
int *number_to_digit(int *n, int *digit_count);
int split_lastDigit(int the_num,int *carryover);
int *long_multiplication(int *multiplicant,int multiplicant_dgcount,int *multiplier,int multiplier_dgcount,int *product_dgcount);
int *add_to_list(int *the_list,int the_value,int *list_count);
int *long_addition(int *addition_dgtslist[],int addition_dgtscount[],int list_count, int *rslt_dgtcount);
int *Factorial_of(int the_num,int *dg_count);

int main()
{
    int i,rsltdgcount;
    int input_number = 1000;
    int *results = Factorial_of(input_number,&rsltdgcount);

    int digits_sum = 0;
    printf("The factorial of %d is ",input_number);
    for(i=(rsltdgcount-1);i>=0;i--)
    {
        digits_sum = digits_sum + (*(results+i));
        printf("%d",*(results+i));
    }

    printf("\n\n");
    printf("Digits sum = %d\nNumber of digits = %d\n",digits_sum,rsltdgcount);

    return 0;
}

int *Factorial_of(int the_num,int *digitcount)
{
    // Returns the factorial of any number the_num
    int i;
    int multicant_dgcount;
    int *result_digits = number_to_digit(&the_num,&multicant_dgcount);// for 100 it stores as 0 0 1 and digitcount = 3

//    int j;
//    for (j=(multicant_dgcount-1);j>=0;j--)
//    {
//        printf("%d",*(result_digits+j) );
//    }
//    printf("\n");

    for(i=(the_num-1);i>1;i--)
    {
        // Convert i to digits
        int multiplier_dgcount;
        int *multi_digits = number_to_digit(&i,&multiplier_dgcount);// for 98 it stores as 8 9 and multiplier_dgcount = 2

        result_digits = long_multiplication(result_digits,multicant_dgcount,multi_digits,multiplier_dgcount,digitcount);
        multicant_dgcount = (*digitcount);

//        for (j=(multicant_dgcount-1);j>=0;j--)
//        {
//            printf("%d",*(result_digits+j) );
//        }
//        printf("\n");
    }

    return result_digits;
}

int *long_addition(int *addition_dgtslist[],int addition_dgtscount[],int list_count, int *rslt_dgtcount)
{
    int i,j;
    // Find the maximum number of digits list
    // Idea is to fill zeroes for shorter numbers (numbers with less digits)
    int max_list_count = 0;
    for(i=0;i<list_count;i++)
    {
        if(max_list_count<addition_dgtscount[i])
        {
            max_list_count = addition_dgtscount[i];
        }
    }

    // Fill zeroes for shorter numbers
    for(i=0;i<list_count;i++)
    {
        for(j=addition_dgtscount[i];j<max_list_count;j++)
        {
            addition_dgtslist[i]=add_to_list(addition_dgtslist[i],0, &addition_dgtscount[i]);
        }

    }
    int *addition_result;
    (*rslt_dgtcount)=0;

    int carry_over = 0;
    int total_sum;

    for(j=0; j<max_list_count ;j++)
    {
        total_sum = carry_over;
        for(i=0;i<(list_count);i++)
        {
            total_sum = total_sum + (*(*(addition_dgtslist+i)+j)) ;
            //printf("%d",*(*(addition_dgtslist+i)+j));
        }
        addition_result=add_to_list(addition_result,split_lastDigit(total_sum,&carry_over),rslt_dgtcount);
    }
    // To add carry Over digits to the list
    int temp_carryover = carry_over;
    if(carry_over!=0)
    {
        addition_result=add_to_list(addition_result,split_lastDigit(temp_carryover,&carry_over),rslt_dgtcount);
        temp_carryover = carry_over;
    }

    return addition_result;
}

int *long_multiplication(int *multiplicant,int multiplicant_dgcount,int *multiplier,int multiplier_dgcount,int *product_dgcount)
{
    int i,j; //Loop variables
    int *product_summ[multiplier_dgcount]; //Variable to hold the digits of each multiplication results level
    int product_summ_dgcount[multiplier_dgcount];
    //printf("\n");
    for(i=0;i<multiplier_dgcount;i++) //Loop thro' all the digits of multiplier 9 4 for 49
    {
        product_summ_dgcount[i] = 0; // set the product digit count as zero
        // Add zeroes at the end
        for(j=0;j<i;j++)// Have to add zeroes at the end of the product sum
        {
            product_summ[i]=add_to_list(product_summ[i],0,&product_summ_dgcount[i]);// added zeroes at the end
        }
        int carry_over = 0; //set the carryover as zero
        int temp_product; // variable to store temporary product
        for(j=0;j<multiplicant_dgcount;j++) //Loop thro' all the digits of multiplicant 4 2 0 1 for 1024
        {
            temp_product = carry_over + ((*(multiplier+i))*(*(multiplicant+j)));
            product_summ[i]=add_to_list(product_summ[i],split_lastDigit(temp_product,&carry_over),&product_summ_dgcount[i]);// added the digit
        }
        //Add the carry over digits to the product_summ
        int carry_over_sum;
        int *carry_over_digits =  number_to_digit(&carry_over,&carry_over_sum); //Split the carry_over digits
        for(j=0;j<carry_over_sum;j++)
        {
             product_summ[i]=add_to_list(product_summ[i],(*(carry_over_digits+j)),&product_summ_dgcount[i]);// added the carry over digits
        }
    }

    // Long addition
//    for(i=0;i<multiplier_dgcount;i++)
//    {
//        // Check the results here
//        for(j=(product_summ_dgcount[i]-1);j>=0;j--)
//        {
//            printf("%d\t",*(product_summ[i]+j));
//        }
//        printf("\n");
//    }
//    printf("\n");

    (*product_dgcount)=0;// Set product digit count as zero
    int *result_product = long_addition(product_summ, product_summ_dgcount,multiplier_dgcount,product_dgcount);
    return result_product;
}

int *add_to_list(int *the_list,int the_value,int *list_count)
{
    if((*list_count)==0)// There is no item in the list
    {
        the_list = (int *)malloc(1*sizeof(int)); // We initialize 1 space to the list
    }
    else
    {
        int *temp = (int *)realloc(the_list,(*(list_count)+1)*sizeof(int)); // Allocate one extra space
        if(temp != NULL)
        {
            the_list = temp;
        }
        else
        {
            printf("Error Allocating Memory");
        }
    }

    *(the_list+(*(list_count))) = the_value; // Adding the value here
    *(list_count) =(*(list_count))+1; // Increment the list count after addition
    return the_list; // return the list address
}


int split_lastDigit(int the_num,int *carryover)
{
    *(carryover) = (int)(the_num/10);
    return (the_num - (*(carryover)*10));
}


int *number_to_digit(int *n, int *digit_count)
{
    int numP,numC = *(n);
    int *digits = (int *)malloc(1*sizeof(int)); //Initially we allocate 1 space to digit list
    *(digit_count) = 0;// set digit_count = 0

    while(numC!=0)
    {
        numP = numC; //Set the numP value as numC then remove the last digit of numC
        //numC = numC/10
        numC=floor(numC/10);
        *(digits+(*(digit_count))) =(int)(numP - (numC*10)); //
        (*(digit_count))=(*(digit_count))+1;//Update the digit count

        int *temp=(int *)realloc(digits,(*(digit_count)+1)*sizeof(int)); // give the pointer some (+1 int) memory each time
        if (temp != NULL )
        {
            digits=temp; //Memory added here
        }
        else
        {
            printf("Error Allocating Memory");
        }
    }
    return digits;// return the digits address and the digit_count is already updated
}

The factorial of 1000 is 402387260077093773543702433923003985719374864210714632543799910429938512398629020592044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759918823627727188732519779505950995276120874975462497043601418278094646496291056393887437886487337119181045825783647849977012476632889835955735432513185323958463075557409114262417474349347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379534524221586593201928090878297308431392844403281231558611036976801357304216168747609675871348312025478589320767169132448426236131412508780208000261683151027341827977704784635868170164365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186116811553615836546984046708975602900950537616475847728421889679646244945160765353408198901385442487984959953319101723355556602139450399736280750137837615307127761926849034352625200015888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838971476088506276862967146674697562911234082439208160153780889893964518263243671616762179168909779911903754031274622289988005195444414282012187361745992642956581746628302955570299024324153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690897968482590125458327168226458066526769958652682272807075781391858178889652208164348344825993266043367660176999612831860788386150279465955131156552036093988180612138558600301435694527224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136493273497565513958720559654228749774011413346962715422845862377387538230483865688976461927383814900140767310446640259899490222221765904339901886018566526485061799702356193897017860040811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614839657382291123125024186649353143970137428531926649875337218940694281434118520158014123344828015051399694290153483077644569099073152433278288269864602789864321139083506217095002597389863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826280956121450994871701244516461260379029309120889086942028510640182154399457156805941872748998094254742173582401063677404595741785160829230135358081840096996372524230560855903700624271243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000


Digits sum = 10539

Number of digits = 2568


Process returned 0 (0x0) execution time : 2.332 s