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