Thread: Working out a factorial using arrays

  1. #1
    Registered User
    Join Date
    Nov 2013
    Posts
    21

    Working out a factorial using arrays

    Hey guys, I'm pretty new to C and have managed (with a little help) to come up with the following code. The code works and comes out with a correct factorial up to 69! (But this is fine I only need it to work up to 60). I was wondering if this could be simplified or optimized in any way. Thanks guys!
    insert
    Code:
    #include <stdio.h>
    
    
    int main(){
    int number[100];        /*Created array of size 100 */
    
    
    int n=34;            /*19931120 summed to make 34 */
    int i;
    
    
    for(i=1; i<=n; i++) {
        int j;
        if (i==1) {
            
            for(j=0; j<99; j++) {                                
                number[j] = 0;        /*Creates base case where all indexes are populated */
            }                        /*with 0s, Except last index which is populated with 1 */
            number[99] = 1;
        } else {
                    
            for(j=0; j<=99; j++) {
                number[j] = number[j] * i;    /*Multiplies index by i */
            
                if(number[j] >= 10) {
                    number[j-1] = number[j-1] + number[j] / 10;   /*If multiplied index is */
                    number[j] = number[j] % 10;        
                }    /*greater than 10, adds tens and hundreds to the index to the left. */
            }    /*Replaces multiplied index with unit alone Loops to multiply all indexes */
            for(j=99; j>=0; j--) {
                
                if(number[j] >= 10) {    //Looping through all the indexes starting at the */
                    number[j-1] = number[j-1] + number[j] / 10; 
                    number[j] = number[j] % 10;        /*end, checks for any greater than 10 */
                }    /*If greater than 10 splits tens and adds to the index to the left. */
            }    /*Leaving single digits in each index. */
        }
    }
    int total = 0;
    
    
    for(i=0; i<100; i++) {
        total = total + number[i];    /*Sums all indexes for printing. */
        printf("%i", number[i]);    /*Printing each index so factorial can be seen. */
    }
    printf("\n");    /*Prints N and sum of the digits of factorial. */
    printf("N is %i, sum is %i\n", n, total);    
    return 0;
    }

  2. #2
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You're doing twice as much work as necessary. You don't need two loops inside your main loop. Try it with just one descending loop (like the second one, but with the multiplication by i).


    It's also wasteful (both space and time) for each element to represent only a single decimal digit when it has far more capacity. It would still be conceptually simple to have them represent 0000 to 9999.


    As for style, you should use a defined constant for your array size.
    And the initialization of the number array should be outside the main loop.
    Also, you don't need to print all the leading zeroes of the answer.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  3. #3
    Registered User
    Join Date
    Nov 2013
    Posts
    21
    So, I've tried cutting out the ascending loop and using a descending loop like you said, but when it comes round to splitting up the numbers into separate arrays (ie 4! = 24, it would split array99 as 4 and array98 as 2), it then multiplies the array98 by i because it hasn't completed that yet... How do I fix this?

  4. #4
    Registered User
    Join Date
    Nov 2013
    Posts
    21
    Here is the code for the above post:
    insert
    Code:
    #include <stdio.h>
    
    
    int main(){
    int number[100];        /*Created array of size 100 */
    {
    int n=34;            /*19940209 summed to make 34 */
    int i;
    
    
    for(i=1; i<=n; i++) {
        int j;
        if (i==1) {
            
            for(j=0; j<99; j++) {                                
                number[j] = 0;        /*Creates base case where all indexes are populated */
            }                        /*with 0s, Except last index which is populated with 1 */
            number[99] = 1;
        } else {
                    
            
            for(j=99; j>=0; j--) {
                number[j] = number[j] * i;
                if(number[j] >= 10) {    //Looping through all the indexes starting at the */
                    number[j-1] = number[j-1] + number[j] / 10; 
                    number[j] = number[j] % 10;        /*end, checks for any greater than 10 */
                }    /*If greater than 10 splits tens and adds to the index to the left. */
            }    /*Leaving single digits in each index. */
        }
    }
    int total = 0;
    
    
    for(i=0; i<100; i++) {
        total = total + number[i];    /*Sums all indexes for printing. */
        printf("%i", number[i]);    /*Printing each index so factorial can be seen. */
    }
    printf("\n");    /*Prints N and sum of the digits of factorial. */
    printf("N is %i, sum is %i\n", n, total);    
    return 0;
    }
    }

  5. #5
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Instead of adding the carry directly into the next element, simply store it as "carry" and add it in when you actually process the next element. Here's a quick rewrite of your program. (It's not well tested since I spent less than 10 minutes on it, but it seems to get the correct answer for 34!.)
    Code:
    #include <stdio.h>
    
    #define SIZE 100
    
    int main() {
        int number[SIZE];
        int n = 34;
        int i, j;
        int total = 0, carry = 0;
     
        for (i = 0; i < SIZE - 1; i++)
            number[i] = 0;
        number[SIZE - 1] = 1;
     
        for (i = 2; i <= n; i++) {
            carry = 0;
            for (j = SIZE - 1; j >= 0; j--) {
                number[j] = number[j] * i + carry;
                if (number[j] >= 10) {
                    carry = number[j] / 10; 
                    number[j] %= 10;
                }else
                    carry = 0;
            }
        }
    
        for (i = 0; i < SIZE && number[i] == 0; i++)
            ;
        if (i == SIZE)
            printf("0");
        else
            for ( ; i < SIZE; i++) {
                total += number[i];
                printf("%d", number[i]);
            }
        printf("\nN is %d, sum is %d\n", n, total);    
    
        return 0;
    }
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Factorial Using recursion not working
    By rrahulvverma in forum C Programming
    Replies: 4
    Last Post: 10-08-2010, 09:00 AM
  2. Help working with functions, structures, and arrays
    By leway in forum C Programming
    Replies: 3
    Last Post: 05-09-2010, 05:24 PM
  3. Replies: 3
    Last Post: 02-24-2009, 08:49 PM
  4. working with arrays
    By brianptodd in forum C++ Programming
    Replies: 1
    Last Post: 11-08-2002, 08:46 PM
  5. working with strings arrays and pointers
    By Nutka in forum C Programming
    Replies: 4
    Last Post: 10-30-2002, 08:32 PM