0
#include<stdio.h>
int fact(int k)
{
int j,f=1;
for(j=1;j<=k;j++)
f*=j;
return f;
}
int main()
{
int t,i,n[100],s[100],j;
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d",&n[i]);
}
for(j=0;j<t;j++)
{
s[j]=fact(n[j]);
printf("%d \n",s[j]);
}
return 0;
}

You are asked to calculate factorials of some small positive integers. Input

An integer t, 1<=t<=100, denoting the number of testcases, followed by t lines, each containing a single integer n, 1<=n<=100. Output

For each integer n given at input, display a line with the value of n! Example

Sample input: 4 1 2 5 3 Sample output: 1 2 120 6

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343

3 Answers3

1

Your code will give correct results for the given test cases but that doesn't prove that your code works. It is wrong is because of integer overflow. Try to calculate 100! by your program and you'll see what's the problem.


My answer lacked details. I'll update this to add details for an answer to the question as it stands now.

C has limitations over the the maximum and minimum size that can be stored in a variable. For doing arbitrary precision arithmetic it is usually advisable to use a bignum library as PHIFounder has suggested.

In the present case however, the use of external libraries is not possible. In this case arrays can be used to store integers exceeding the maximum value of the integers possible. OP has already found this possibility and used it. Her implementation, however, can use many optimizations.

Initially the use of large arrays like that can be reduced. Instead of using an array of 100 variables a single variable can be used to store the test cases. The use of large array and reading in test cases can give optimization only if you are using buffers to read in from stdin otherwise it won't be any better than calling scanf for reading the test cases by adding a scanf in the for loop for going over individual test cases.

It's your choice to either use buffering to get speed improvement or making a single integer instead of an array of 100 integers. In both the cases there will be improvements over the current solution linked to, on codechef, by the OP. For buffering you can refer to this question. If you see the timing results on codechef the result of buffering might not be visible because the number of operations in the rest of the logic is high.

Now second thing about the use of array[200]. The blog tutorial on codechef uses an array of 200 elements for demonstrating the logic. It is a naive approach as the tutorial itself points out. Storing a single digit at each array location is a huge waste of memory. That approach also leads to much more operations leading to a slower solution. An integer can at least store 5 digits (-32768 to 32767) and can generally store more. You can store the intermediate results in a long long int used as your temp and use all 5 digits. That simplification itself would lead to the use of only arr[40] instead of arr[200]. The code would need some additional changes to take care of forward carry and would become a little more complex but both speed and memory improvements would be visible.

You can refer to this for seeing my solutions or you can see this specific solution. I was able to take the use down to 26 elements only and it might be possible to take it further down.

I'll suggest you to put up your code on codereview for getting your code reviewed. There are many more issues that would be best reviewed there.

Community
  • 1
  • 1
Aseem Bansal
  • 6,722
  • 13
  • 46
  • 84
  • @PHIfounder you helped me getting out of that run time error thingy..and your answer was correct , but then i changed my question and here is a solution to that http://blog.codechef.com/2009/07/02/tutorial-for-small-factorials/ – Neha Nagori Jul 12 '13 at 18:09
  • @NehaNagori Ok, but I answered as per your problem here, not as per codechef and its ok , but you accepted an answer that is not totally answer to your specified problem here , one more thing I didn't see the codechef problem at all because I was answering specific to this problem. Any way get going :) – 0decimal0 Jul 12 '13 at 18:15
  • This is not an answer, you are just describing the possible bug in the code and that too after OP changed the question . Instead of just pointing out the error you should have at least briefly described what needs to be done to calculate the factorial because in standard C no type has been defined to take that huge a number. Either one will have to completely change his implementation or use some external libraries. Take a look at this post :http://stackoverflow.com/questions/8133984/storing-a-number-greater-than-20-factorial – 0decimal0 Jul 13 '13 at 00:36
  • @PHIfounder here is the correct code : http://www.codechef.com/viewsolution/2369021 – Neha Nagori Jul 13 '13 at 14:23
  • @NehaNagori Yes that's right ,storing anything like factorial 100 is not defined in any standard specially in C .So what has been done is actually storing the last digits of product of the consecutive numbers in an array. That's good. – 0decimal0 Jul 13 '13 at 14:28
  • 1
    @PHIfounder I didn't see the details of edits to the question. My mom was going to switch off the internet to make me sleep so I wrote this down to give her a heads up about the bug that was causing it to fail. I'll update this with proper details. – Aseem Bansal Jul 15 '13 at 04:27
  • @NehaNagori Just one thing about stackoveflow, you don't need to accept an answer in hurry. You can take your time and accept an answer only after you are sure. You can edit the question for new bugs that you are encountering. No restriction about that. – Aseem Bansal Jul 15 '13 at 04:41
  • 1
    @AseemBansal Normally , the edit like the one done by OP is irresponsible because subsequent edits highlighted different problems which on her part is pretty bad. She should have either thought about completing implementation on her own or just posted about errors or she could have simply posted about implementation of factorial after solving the error issues on her own. This confuses the ones who answers because by then their answer would have no relevance to the question as it has been edited and they can neither remove the answer nor can they do anything. – 0decimal0 Jul 15 '13 at 05:24
  • @PHIfounder New people make mistakes. I'll give her a link about how to properly update questions. – Aseem Bansal Jul 15 '13 at 05:46
  • @NehaNagori Please take a look at [this question](http://codereview.stackexchange.com/questions/28285/binary-search-in-c-optimization) to see how to properly update question when you are facing new bugs in the same problem. It makes answering your question easier for people leading to you getting better answers. – Aseem Bansal Jul 15 '13 at 05:48
  • @AseemBansal that would be much better , +1 for your explanation – 0decimal0 Jul 15 '13 at 05:49
  • Look the question by codechef was same from the starting that is 1 – Neha Nagori Jul 15 '13 at 12:39
  • @NehaNagori We weren't talking about the codechef problem statement. It was about your question here. The edit to the question here caused some confusion so this suggestion came up. Did my answer help somewhat? – Aseem Bansal Jul 15 '13 at 12:42
0

Here, your array index should start with 0 not 1 , I mean j and ishould be initialized to 0 in for loop.

Besides, try to use a debugger , that will assist you in finding bugs.

And if my guess is right you use turbo C, if yes then my recommendation is that you start using MinGW or Cygwin and try to compile on CLI, anyway just a recommendation.

There may be one more problem may be which is why codechef is not accepting your code you have defined function to accept the integer and then you are passing the array , may be this code will work for you:

#include<stdio.h>
int fact(int a[],int n)// here in function prototype I have defined it to take array as argument where n is array size.
{
  int j=0,f=1,k;
  for (k=a[j];k>0;k--)
    f*=k;
  return f;
}
int main()
{
  int t,i,n[100],s[100],j;
  setbuf(stdout,NULL);
  printf("enter the test cases\n");
  scanf("%d",&t); //given t test cases
  for(i=0;i<t;i++)
    {
      scanf("%d",&n[i]); //value of the test cases whose factorial is to be calculated
    }
  for(j=0;j<t;j++)
    {
      s[j]=fact(&n[j],t);// and here I have passed it as required 

      printf("\n %d",s[j]); //output
     }
  return 0;
}

NOTE:- After the last edit by OP this implementation has some limitations , it can't calculate factorials for larger numbers say for 100 , again the edit has taken the question on a different track and this answer is fit only for small factorials

0decimal0
  • 3,884
  • 2
  • 24
  • 39
  • I am using Dev C++, and it is running error free on that, but when i submit same code(withiout conio.h and getch) on codechef its giving me a runtime – Neha Nagori Jul 12 '13 at 14:42
  • please check the edited code above, though there is no run time error in this code, codechef declares it as wrong answer, then i submitted your code there still "wrong answer". – Neha Nagori Jul 12 '13 at 17:13
  • @NehaNagori Did you run it on your system ? Do you get correct results? May be the problem was different. Because it worked on my system . – 0decimal0 Jul 12 '13 at 17:17
  • Correct on my system, but codechef is still declaring it as wrong answer – Neha Nagori Jul 12 '13 at 17:26
  • @NehaNagori You have accepted this answer. But it would give wrong answer. Did you figure it out for yourself or should I answer this? – Aseem Bansal Jul 12 '13 at 17:44
  • @aseem i have accepted it as the answer as it is running successfully on my compiler, but codechef is not taking it as a correct answer – Neha Nagori Jul 12 '13 at 17:54
  • 1
    And moreover i guess i know where am i wrong now, int cannot accomodate 100! in itself may be that is why codechef is saying "wrong answer" – Neha Nagori Jul 12 '13 at 17:56
0

above program works only for small numbers that means upto 7!,after that that code not gives the correct results because 8! value is 40320 In c language SIGNED INTEGER range is -32768 to +32767 but the >8 factorial values is beyond that value so integer cant store those values so above code can not give the right results for getting correct values we declare the s[100] as LONG INT,But it is also work only for some range