3

I want to calculate the sum of digits of N!.

I want to do this for really large values of N, say N(1500). I am not using .NET 4.0. I cannot use the BigInteger class to solve this.

Can this be solved by some other algorithm or procedure? Please help.

I want to do some thing like this Calculate the factorial of an arbitrarily large number, showing all the digits but in C#. However I am unable to solve.

Community
  • 1
  • 1
user873244
  • 51
  • 1
  • 4
  • 5
    Telling us which platform you *aren't* using isn't really helping. – skaffman Aug 01 '11 at 22:36
  • Same question is answered in some other forum. Check this http://stackoverflow.com/questions/1384160/calculating-factorial-of-large-numbers-in-c – questborn Aug 01 '11 at 22:37
  • Why do you need to take factorials of such large numbers? What will you do with the results? – giltanis Aug 01 '11 at 22:39
  • 4
    @user873580- This isn't an exact duplicate, since the goal is to find the sum of the digits, not the digits themselves. This is actually a very interesting algorithms question. – templatetypedef Aug 01 '11 at 22:43
  • @templatetypedef: I don't think there is a "nice" way to get the sum though - its not like this is some nice modular arithmetic problem. – hugomg Aug 01 '11 at 22:47
  • 1
    Not a .NET answer (unless you use IronPython which would require 4.0) but in Python you can do `import math` `sum(map(int,str(math.factorial(1500))))` which gives 16749 – Davy8 Aug 01 '11 at 22:49
  • Well, in python doesn't count - you can also do `import antigravity` – hugomg Aug 01 '11 at 22:56
  • 1
    http://stackoverflow.com/questions/1469529/sum-of-digits-of-a-factorial – tskuzzy Aug 02 '11 at 00:37
  • A cute, and trivial question, is to ask what is the digital root of the factorial of a VERY large number, say 1e12. I.e., sum the digits, and then sum the digits of that result, until you are left with a single digit result. –  Aug 02 '11 at 00:49
  • http://www.wolframalpha.com/input/?i=sum+of+digits+of+%281500!%29 – Dr. belisarius Aug 02 '11 at 12:52

7 Answers7

1

There is no special magic that allows you to calculate the sum of the digits, as far as I am concerned.

It shouldn't be that hard to create your own BigInteger class anyway - you only need to implement the long multiplication algorithm from 3rd grade.

hugomg
  • 68,213
  • 24
  • 160
  • 246
  • I want to do some thing like this...but in C#..but not able to solve http://stackoverflow.com/questions/1966077/calculate-the-factorial-of-an-arbitrarily-large-number-showing-all-the-digits – user873244 Aug 01 '11 at 22:46
  • +1, best answer imho. Just implement some vanilla multiplication algorithm based on strings, and presto. – Gleno Aug 01 '11 at 22:54
1

If your goal is to calculate the sum of the digits of N!, and if N is reasonably bounded, you can do the following without a BigInteger type:

  • Find a list of factorial values online (table lookup will be much more efficient than calculating from scratch, and does not require BigInteger)
  • Store as a string data type
  • Parse each character in the string as an integer
  • Add the resulting integers
Eric J.
  • 147,927
  • 63
  • 340
  • 553
  • Well, you might as well just store the sum of digits then. :P – hugomg Aug 01 '11 at 22:45
  • I want to do some thing like this...but in C#..but not able to solve http://stackoverflow.com/questions/1966077/calculate-the-factorial-of-an-arbitrarily-large-number-showing-all-the-digits – user873244 Aug 01 '11 at 22:46
  • @missingno: Sure :-) The primary reason I posted that answer actually is to remind people that lookup tables are sometimes a valid solution. – Eric J. Aug 01 '11 at 22:51
  • There's an open source BigInteger implementation from 2002 that you could use http://www.codeproject.com/KB/cs/biginteger.aspx – Eric J. Aug 01 '11 at 22:54
1

There are two performance shortcuts that you can use for whatever implementation you choose.

  1. Chop off any zeros from the numbers.
  2. If the number is evenly divisible by 5^n, divide it by 10^n.

in this way,

16*15*14*13*12*11*10*9*8*7*6*5*4*3*2 = 20,922,789,888,000
//-->
16*1.5*14*13*12*11*1*9*8*7*6*0.5*4*3*2 = 20,922,789,888 //Sum of 63

Also, it feels like there should be some algorithm without reverting to calculating it all out. Going to 18!, the sums of the digits are:

2,6,6,3,9,9,9,27,27,36,27,27,45,45,63,63,63
//the sums of the resulting digits are:
2,6,6,3,9,9,9,9,9,9,9,9,9,9,9,9,9

and notably, the sum of the digits of 1500! is 16749 (the sum of whose digits are 27)

Jacob Eggers
  • 9,062
  • 2
  • 25
  • 43
  • According to the OEIS (http://oeis.org/search?q=2%2C6%2C6%2C3%2C9%2C9%2C9%2C27%2C27&language=english&go=Search), the sum is divisible by 9 for all n>5. – mhum Aug 02 '11 at 16:37
  • 1
    Yeah, I remember from my middle school days that any number divisible by 3 has digits whose sum is divisible by 3 and the same for 9. So that would be the case. – Jacob Eggers Aug 02 '11 at 17:45
0

you can find the source code at : http://codingloverlavi.blogspot.in/2013/03/here-is-one-more-interesting-program.html

#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<time.h>
#define max 5000
void multiply(long int *,long int);
void factorial(long int *,long int);


int main()
{
clrscr();
cout<<"PROGRAM TO CALCULATE FACTORIAL OF A NUMBER";
cout<<"\nENTER THE NUMBER\n";
long int num;
cin>>num;

long int a[max];
for(long int i=0;i<max;i++)
    a[i]=0;

factorial(a,num);

clrscr();

//PRINTING THE FINAL ARRAY...:):):)
cout<<"THE FACTORIAL OF "<<num<<" is "<<endl<<endl;
long int flag=0;

int ans=0;
for(i=0;i<max;i++)
{
    if(flag||a[i]!=0)
    {
        flag=1;
        cout<<a[i];
        ans=ans+a[i];
    }
}

cout<<endl<<endl<<"the sum of all digits is: "<<ans;


getch();
return 1;
}

void factorial(long int *a,long int n)
{
long int lavish;
long int num=n;
lavish=n;
for(long int i=max-1;i>=0&&n;i--)
{
    a[i]=n%10;
    n=n/10;
}

for(i=2;i<(lavish);i++)
{
    multiply(a,num-1);
    num=num-1;

}
}


void multiply(long int *a,long int n)
{

for(long int i=0;i<max;i++)
    a[i]=a[i]*n;

for(i=max-1;i>0;i--)
{
    a[i-1]=a[i-1]+(a[i]/10);
    a[i]=a[i]%10;
}
}
Lavish Kothari
  • 2,211
  • 21
  • 29
0

Here's some working code. Some components can be improved upon to increase efficiency. The idea is to use whatever multiplication algorithm I was told in school, and to store long integers as strings.

As an afterthought, I think it would be smarter to represent large numbers with List<int>() instead of string. But I'll leave that as an exercise to the reader.

Code Sample

static string Mult(string a, string b)
    {
        int shift = 0;
        List<int> result = new List<int>();
        foreach (int aDigit in a.Reverse().Select(c => int.Parse(c.ToString())))
        {
            List<int> subresult = new List<int>();
            int store = 0;
            foreach (int bDigit in b.Reverse().Select(c => int.Parse(c.ToString())))
            {
                int next = aDigit*bDigit + store;
                subresult.Add(next%10);
                store = next/10;
            }

            if (store != 0) subresult.Add(store);

            subresult.Reverse();
            for (int i = 0; i < shift; ++i) subresult.Add(0);
            subresult.Reverse();

            int newResult = new List<int>();
            store = 0;
            for (int i = 0; i < subresult.Count; ++i)
                {
                    if (result.Count >= i + 1)
                    {
                        int next = subresult[i] + result[i] + store;
                        if (next >= 10)
                            newResult.Add(next % 10);
                        else newResult.Add(next);
                        store = next / 10;
                    }
                    else
                    {
                        int next = subresult[i] + store;
                        newResult.Add(next % 10);
                        store = next / 10;
                    }
                }

            if (store != 0) newResult.Add(store);

            result = newResult;
            ++shift;
        }

        result.Reverse();
        return string.Join("", result);
    }

    static int FactorialSum(int n)
    {
        string result = "1";
        for (int i = 2; i <= n; i++)
            result = Mult(i.ToString(), result);
        return result.Sum(r => int.Parse(r.ToString()));
    }

Code Testing

Assuming the code snippet above is in the same class as your Main method, call it thusly.

Input

    static void Main(string[] args)
    {
        Console.WriteLine(FactorialSum(1500));
    }

Output

16749
Gleno
  • 16,621
  • 12
  • 64
  • 85
0

Here's a port of the C++ code you reference in one of your comments. One thing to realize when porting from C++ to C# is that integers that are zero evaluate to false and integers that are non-zero evaluate to true when used in a Boolean comparison.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ArbitraryFactorial
{
    class Program
    {
        const int max = 5000;

        static void display(int[] arr)
        {
            int ctr = 0;
            for (int i = 0; i < max; i++)
            {
                if (ctr == 0 && arr[i] != 0) ctr = 1;
                if (ctr != 0)
                    Console.Write(arr[i]);

            }
        }

        static void factorial(int[] arr, int n)
        {
            if (n == 0) return;
            int carry = 0;
            for (int i = max - 1; i >= 0; --i)
            {
                arr[i] = (arr[i] * n) + carry;
                carry = arr[i] / 10;
                arr[i] %= 10;
            }
            factorial(arr, n - 1);
        }

        static void Main(string[] args)
        {
            int[] arr = new int[max];
            arr[max - 1] = 1;
            int num;
            Console.Write("Enter the number: ");
            num = int.Parse(Console.ReadLine());
            Console.Write("Factorial of " + num + " is: ");
            factorial(arr, num);
            display(arr);
        }
    }
}
Community
  • 1
  • 1
Eric J.
  • 147,927
  • 63
  • 340
  • 553
-1

You can't use these numbers at all without a BigInteger type.
No algorithm or procedure can squeeze numbers larger than 264 into a long.

You need to find a BigInteger implementation for .Net 3.5.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    There may be an algorithm for summing together the digits of N! without necessarily holding it all in memory. In that case, BigInteger might not be necessary at all. – templatetypedef Aug 01 '11 at 22:38
  • I want to do some thing like this...but in C#..but not able to solve http://stackoverflow.com/questions/1966077/calculate-the-factorial-of-an-arbitrarily-large-number-showing-all-the-digits – user873244 Aug 01 '11 at 22:46