CodeChef is a non-commercial competitive programming community
Login
Username (New User? Signup) Password (Forgot Password?)
Signup
Login or
Signup with
Connect
Note
  • Publicize your achievements on your Facebook Wall.
  • Challenge your friends or ask them for help.

Site Navigation

  • PRACTICE
    • Easy
    • Medium
    • Hard
    • Challenge
    • Peer
  • COMPETE
    • February CookOff
    • February Long Contest
    • January CookOff
  • DISCUSS
    • Wiki
    • Forums
    • Blog
    • Twitter
  • COMMUNITY
    • CodeChef Meetups
    • Campus Chapters
    • Host your Contest
    • User Groups
    • CodeChef TechTalks
    • All Educational Initiatives
    • Event Calendar
  • HELP
    • Frequently Asked Questions
    • FAQ for problem setters
    • Problem Setting
    • Ranks
    • Tutorials
  • ABOUT
    • About CodeChef
    • Team CodeChef
    • Press Room
    • CodeChef Financials
    • CodeChef Sponsorships
    • CEO's Corner
    • Contact Us
    • About Directi
Home » Wiki » Tutorial for Small Factorials

Tutorial for Small Factorials

Hello all !

The problem that we will be taking up is http://www.codechef.com/problems/FCTRL2/ :)
This problem basically asks you to calculate the factorial of a number up to 100. Now, I guess most of you know what a "factorial" is. For those who don't, the factorial of a number N is 1*2*...*N. This problem would be very simple, had it not been for the maximum value of N. The structure of the problem is such that it asks the user to take the number of test cases as the first input. Then 't' integers follow where 't' is the number of test cases which was given as input previously.

For every integer here, we have to calculate the factorial. This is very simple in languages like python or java which have built-in support for big integer types. It proves to be a hassle for people using C / C++ or languages that do not have a built-in biginteger type. Let's think about how we can store the the result.

Now, the maximum number that we can store in an unsigned 32 bit integer is 2 ^ 32 - 1 and in an unsigned 64 bit integer is 2 ^ 64 - 1. Something like 100!('!' is the notation for factorial) has over 150 decimal digits. The data types mentioned earlier can store numbers having at most 9 and 19 decimal digits respectively. So, we need to find a way to store the 150+ digits that we will get as the answer. The simplest data structure that we can use is an integer array of size of about 200 to be on the safe side.

In the simplest form, let us store one decimal digit per array index. So, if the number is say 120, then the array will have the numbers as follows:

Say a[200] is how we declare the array, then
a[0] = 0
a[1] = 2
a[2] = 1

The least significant digit is stored in the lowest index 0. The next one in index 1 and so on. Along with the array, we need an integer specifying the total number of digits in the array at the given moment. Let this number be 'm'. Initially, a[0] will be 1 and the value of 'm' will be 1 specifying that we have just one digit in the array.

Let's take a simple example first. Consider that the array has some value like 45 and we need to multiply it with a value 37. This can be done in the following way.
The array will be:
a[0] = 5
a[1] = 4
and the value of m will be 2 specifying that there are 2 digits in the array currently.

Now, to multiply this array with the value 37. We start off from the index 0 of the array to index 1. At every iteration, we calculate 37 * a[index]. We also maintain a temporary variable called temp which is initialized to 0. Now, at every step, we calculate x = a[index] * 37 + temp. The new value of a[index] will be x % 10 and the new value of temp will be temp / 10. We are simply carrying out multiplication the way it is carried out usually. So, for the current situation, the iterations will be something like this.

Initialize temp = 0
Iteration 1 :
array = (5, 4)
temp = 0
index = 0, a[index] = 5
x = a[index] * 37 + temp = 5 * 37 + 0 = 185.
the new value of a[index] = 185 % 10 which is 5 and the new value of temp is 185 / 10 which is 18

Iteration 2 :
array : (5, 4)
temp = 18
index = 1, a[index] = 4
x = a[index] * 37 + temp = 4 * 37 + 18 = 166.
the new value of a[index] = 166 % 10 which is 6 and the new value of temp is 166 / 10 which is 16

We have finished 2 iterations and this is the value of 'm', the array size at the moment. The required number of iterations is now over, but the value of temp is still greater than 0. This means that the current value of temp is to be incorporated into the array. For that, we keep appending the last digit of temp to the array and divide temp by 10 till temp becomes 0. So, we will get something like
Iteration 1 :
temp = 16 , array = (5, 6)
So, we add 16 % 10 to the array so that the array becomes (5, 6, 6) and we divide temp by 10 so that temp becomes 1. We update the value of 'm' to m + 1 that is m = 3
Iteration 2 :
temp = 1, array = (5, 6, 6)
Now, we add 1 % 10 to the array so the array becomes (5, 6, 6, 1) and we divide temp by 10 so that temp becomes 0. We update the value of 'm' to m + 1 that is m = 4

The value of temp is now 0 and our multiplication is now over. The final array we get is (5, 6, 6, 1)

Voila, we have the answer to 45 * 37 in our array with the Least significant digit in the 0th position. :)

For finding the factorial, we need to carry out this exact multiplication operation at every step as we loop from 1 to N. At the end of the Nth iteration, our array will contain
the answer and the value of m will be the number of digits in the answer. We can then just print the array from the Most significant digit to the least for the answer.

The basic flow of the program will be as below :

[code]

Start

Take in the number of test cases

While there is a test case remaining to be handled

Take in the number whose factorial is to be found, let it be N

Initialize the arrays 0th index to 1 and m to 1

Initialize i to 1

While i is less than or equal to N

Carry out multiplication of the array with 'i' as shown above.

Print the contents of the array starting from the most significant digit and ending with the least significant digit.

Stop

[/code]

Certain improvements can be made to the above mentioned method. We are storing only one digit per array index, We can store more than 1 digit per index so that the number of computations are reduced. The method to do that is the same as above. We leave it to the reader as an exercise :)


Comments

  • Login or Register to post a comment.

If the number of test cases

hunnysingh @ 29 Nov 2009 11:21 PM

If the number of test cases is high, why dont we preprocess all the factorials and store them as char * and then as we get the input we just flush out the stored number. Such preprocessing will be useful when any test case value can be = N.

Thanks , good tutorial .

magiix @ 30 Nov 2009 09:15 PM

Thanks , good tutorial .

i need some sample

jeevi @ 1 Dec 2009 04:39 PM

i need some sample programs..... pls

great tutorial ty:):):)

maagi @ 4 Dec 2009 09:27 AM

great tutorial ty:):):)

wow! what a tutorial!! it

jagadish1989 @ 20 Dec 2009 06:41 AM

wow! what a tutorial!! it enlightened me a lot thanks a tonne admin :) :)

thnx ! !

Geniusguy @ 30 Dec 2009 11:00 PM

thnx ! !

great

sahilsingla @ 11 Jan 2010 11:43 PM

great tutorial.............:)   it opened closed doors of my brain....

That Really Helped!

Fahim Dalvi @ 12 Jan 2010 09:07 PM

That Really Helped!

nice trick!

chandniverma @ 20 Jan 2010 08:39 AM

nice trick!

AN EXCELLENT ONE!! REALLY

letusc @ 27 Jan 2010 01:22 AM

AN EXCELLENT ONE!! REALLY AWESOME

GOOD TUTORIAL

enigmatickoder @ 27 Jan 2010 03:16 PM

GOOD TUTORIAL

awesome, it teaches a simple

abhinavupadhya @ 31 Jan 2010 02:59 AM

awesome, it teaches a simple and easy way to represent very large values in our C programs, this is very much appreciated!!

thanks :-)

great tutorial

legendofseeker @ 3 Feb 2010 05:32 PM

great tutorial

#include<stdio.h>#include<str

magiix @ 9 Feb 2010 06:20 AM

#include<stdio.h>
#include<string>
#include<string.h>
using namespace std;
char arr[200],res[200];
string table[150];

string multiply(string n,int m)
{
int N=n.size(),M=N,temp=0;
for(int i=0;i<N;i++)
arr[i]=n[N-1-i];
for(int i=0;i<N;i++)
{
int x=m*arr[i]+temp;
arr[i]=x%10;
temp=x/10;
}
while(temp>0)
{
arr[N]=temp%10;
temp/=10;
N++;
}
for(int i=0;i<M;i++)
res[i]=arr[M-1-i];
return res;
}
void make_table()
{
table[1]='1';
for(int i=2;i<101;i++)
{
table[i]=multiply(table[i-1],i);
}
}
int main()
{
int tc,n;
scanf(" %d",&tc);
make_table();
while(tc--)
{
scanf(" %d",&n);
printf("%sn",table[n]);
}
return 0;
}


can anyone help me fix my code ???

I fixed it Thanks :D

magiix @ 10 Feb 2010 06:48 AM

I fixed it Thanks :D

even java doesn't give

shubh09 @ 13 Feb 2010 03:18 PM

even java doesn't give correct answers if we try to compute factorials of nos. greater than 20 even after using the long data type. this trick really helps...

Really helped me..tnx..

bharathgowri @ 27 Feb 2010 08:42 AM

Really helped me..tnx..

n1

dharmik @ 2 Mar 2010 06:28 AM

n1

why do use this "using

udit_rastogi @ 18 Mar 2010 03:32 PM

why do use this

"using namespace std;"

i didn't study it in which compiler this is used.

i study c++ in 12 with sumita arora book..

so in which compiler i have to write the program

Great tutorial! Thanks....

shashankl @ 26 Mar 2010 07:54 PM

Great tutorial! Thanks....

Good Tutorial, Really

S-Harpreet @ 28 Mar 2010 06:50 PM

Good Tutorial, Really helpful, thanx

great man good use of data

tipsy25187 @ 12 May 2010 07:08 PM

great man good use of data stuructures

trick is awesome!!

amartyaamp @ 8 Jun 2010 03:33 PM

trick is awesome!!

@udit rastogi : we used turbo

DJ_rocks @ 13 Jun 2010 11:21 AM

@udit rastogi : we used turbo C to program in class 12 from sumita arora. I'd recommend the same to you

Awesome tutorial thanx Admin

DevilsEye @ 22 Jun 2010 12:38 PM

Awesome tutorial thanx Admin for posting this it really helped...now we can compute any length of digit..:D

@Admin :How did you get the

sloth @ 30 Jul 2010 11:23 PM

@Admin :How did you get the LSB in lowest array index  ?

great tutorial!!!! really

aabidhasan @ 2 Aug 2010 09:57 AM

great tutorial!!!! really helpful

dat was truely informative!!!

ejoe @ 18 Sep 2010 08:02 AM

dat was truely informative!!!

awesome tutorial !!

naveenraiit @ 26 Sep 2010 05:59 PM

awesome tutorial !!

its awesome

janardhan7 @ 27 Sep 2010 05:52 PM

its awesome

Can someone show me the code?

knightyau @ 17 Oct 2010 08:13 PM

Can someone show me the code? cant understand very well :(

Please reply me need help :(

knightyau @ 17 Oct 2010 08:15 PM

Please reply me need help :( thanks in advanced.wanna learn this very desperately.

i get it thanks ;)

knightyau @ 20 Oct 2010 09:48 PM

i get it thanks ;)

this frickin awesome!! <3

ankeetmaini @ 9 Nov 2010 06:19 PM

this frickin awesome!! <3

nice tutorial !   really nice

rabba_alam @ 24 Nov 2010 07:17 AM

nice tutorial !   really nice thanks  !!!!

Nice tutorial... :)

bithin2007 @ 25 Nov 2010 06:18 PM

Nice tutorial... :)

#include<iostream>   using

kezzy @ 4 Jan 2011 08:29 PM

#include<iostream>

 

using namespace std;

 

int main(void){

int t,m,i,p=0,k=0;

cin>>t;

int a[1000][1000];

while(t--){

long int x,n,r;

cin>>n;

a[p][0]=i=1;

r=n;

while(n){

a[p][m++]=n%10;

n/=10;

}

long int temp=0;

for(int j=r-1,i=0;j>0;j--,i++){

while(k==m){

x=a[p][i]*j+temp;

a[p][i]=x%10;

temp=x/10;

k++;

}

while(temp){

a[p][i++]=temp%10;

temp/=10;

}

}

p++;

}

for(k=0;k<=p;k++){

for(int j=i--;j>=0;j--){

cout<<a[k][j];

}

cout<<"n";

}

}

the code compiles but it isnt running. it shows some kind of error

GooD Tut

kooljay999 @ 16 Feb 2011 02:59 AM

GooD Tut

great tutorial!!!! really

bsp23 @ 4 Mar 2011 04:32 PM

great tutorial!!!! really helpful

great tutorial thanxxxxxx :)

Garry @ 21 Mar 2011 07:57 PM

great tutorial thanxxxxxx :)

awesome trick .. .thanx. .

ratz @ 31 Mar 2011 11:53 AM

awesome trick .. .thanx. .

ooooooooooooookkkkkkkkkkkkkkk

apudxtr @ 8 Apr 2011 03:31 PM

ooooooooooooookkkkkkkkkkkkkkkkkkkkkkk........thnx man.

thanx a lot, great tutorial

princeofpersia @ 18 Apr 2011 01:57 PM

thanx a lot, great tutorial !

 

Awesome tutorial

lordaragon @ 1 May 2011 07:49 PM

Awesome tutorial

hi i need a sample java

sampathmse @ 10 May 2011 11:24 AM

hi i need a sample java program pls ....

AWESOME,,,,,,SUPERB TUTE

hungrycoder @ 16 Jun 2011 07:58 PM
AWESOME,,,,,,SUPERB TUTE

nice 1.. thanx

bootstrap @ 20 Jun 2011 10:55 PM
nice 1.. thanx

awsome one budy ...thanks a

gupta @ 15 Aug 2011 08:48 PM
awsome one budy ...thanks a lot

Sorry for stupid questions

gennadz @ 14 Sep 2011 07:34 PM
Sorry for stupid questions but why we % 10 and / 10, what is the technique of multiplication?

thanx for the tutorial......

balabarath @ 21 Sep 2011 08:56 PM
thanx for the tutorial......

thankz a ton..gr8 tut..

ritanjandawn @ 24 Sep 2011 02:50 PM
thankz a ton..gr8 tut..

The following code runs

buzz92 @ 30 Sep 2011 03:44 PM
The following code runs properly in my computer but when i submit it says wrong answer...can somebody please help me! #include int main() { int a[200],n,no,i,j,m,k,x,l,temp,d; scanf("%d",&n); for(i=0;i=0;l--) printf("%d",a[l]); for(d=0;d

awesome!!!

riseabove @ 1 Oct 2011 11:25 PM
awesome!!!

Great tutorial! Thanks a lot

cinash @ 3 Oct 2011 07:18 AM
Great tutorial! Thanks a lot :)

AWESOME!!!

sinha2011 @ 4 Oct 2011 04:43 PM
AWESOME!!!

java has BIGINTEGER type data

checklist @ 8 Oct 2011 02:17 PM
java has BIGINTEGER type data type which will be usefull for such cases...

The only error I get is an

divyamrastogi @ 27 Nov 2011 04:00 PM
The only error I get is an extra '1' is added when I calculate 100! Can somebody help me with this. It seems to be a small bug.

#include int main() {int

anshu1710 @ 18 Dec 2011 04:28 PM
#include int main() {int t,n; int x; scanf("%d",&t); while(t>0) {t--; scanf("%d",&n); x=1; for(;n>0;n--) x=n*x; printf("%d",x); } return(0); } what is the problem with this code??

check it for nos greater than

goudam_jm @ 19 Dec 2011 02:53 PM
check it for nos greater than 20

tanx :)))

tj91 @ 29 Dec 2011 06:52 PM
tanx :)))

its very nice

rky_rajkumar @ 29 Dec 2011 07:18 PM
its very nice

#include int a[100]; void

sandeepsuraj7 @ 11 Jan 2012 12:03 PM
#include int a[100]; void main() { int n,i,temp=1,x=1,j; cout<<"enter a number"; cin>>n; cout<
CodeChef is a non-commercial competitive programming community
  • About CodeChef
  • About Directi
  • CEO's Corner
  • C-Programming
  • Programming Languages
  • Contact Us
© 2009 Directi Group. All Rights Reserved. CodeChef uses SPOJ © by Sphere Research Labs
In order to report copyright violations of any kind, send in an email to copyright@codechef.com
CodeChef a product of Directi
The time now is:
CodeChef - A Platform for Aspiring Programmers

CodeChef was created as a platform to help programmers make it big in the world of computer programming. At CodeChef we work hard to revive the geek in you by hosting programming contests on a monthly basis. We also aim to have training sessions and events related to online programming for programmers around the world. Apart from providing a platform for programming competitions, CodeChef also has various tutorials and forum discussions to help those who are new to the world of computer programming.

Practice Section - A Place to hone your 'Computer Programming Skills'

Try your hand at one of our many practice problems and submit your solution in a language of your choice. Our judge accepts solutions in over 35+ programming languages. Online programming was never this much fun! Receive points, and move up through the CodeChef ranks. Use our practice section to better prepare yourself for the multiple programming competitions that take place through-out the month on CodeChef.

Compete - Monthly Programming Contests and Cook-offs

Here is where you can show off your computer programming skills. Take part in our 10 day long monthly programming contests and the shorter format Cook-off programming contests. Put yourself up for recognition and win great prizes. Prizes worth up to Rs.20,000 and $700 are up for grabs every month along with lots more CodeChef goodies.

Discuss

Are you new to computer programming? Do you need help with algorithms? Then be part of CodeChefs Forums and interact with all our programmers love helping out other programmers and share their ideas.

CodeChef Community

As part of our Educational initiative, we give institutes the opportunity to associate with CodeChef in the form of Campus Chapters. Hosting online programming competitions is not the only feature on CodeChef. Be a part of the CodeChef community through CodeChef meetups and techtalks. You can also host a programming contest for your institute on CodeChef and be a guest author on our blog.

Domain Name Registration, Web hosting, and Website Design provided by BigRock.com