26
\$\begingroup\$

The challenge is to calculate the digit sum of the factorial of a number.


Example

Input: 10
Output: 27

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

You can expect the input to be an integer above 0. Output can be of any type, but the answer should be in the standard base of the coding language.


Test cases:

10    27
19    45
469   4140
985   10053

N.B. Some languages can not support large numbers above 32-bit integers; for those languages you will not be expected to calculate large factorials.

OEIS link here thanks to Martin Ender


This is , so shortest code in characters wins!

\$\endgroup\$
2
  • \$\begingroup\$ What's the maximum input number to expect? With 32-bit integers in R this challenge can't be solved accurately past n>21 \$\endgroup\$
    – Billywob
    Nov 23 '16 at 15:22
  • 2
    \$\begingroup\$ @Billywob For R then you will only need to go to 20. I shall edit question to reflect this \$\endgroup\$
    – george
    Nov 23 '16 at 15:23

53 Answers 53

1
2
1
\$\begingroup\$

C, 63 60 bytes

-3 byte for do...while loop.

i;f(n){i=n;while(--n)i*=n;do n+=i%10;while(i/=10);return n;}

Ungolfed and usage:

i;
f(n){
 i=n;
 while(--n)
  i*=n;
 do
  n+=i%10;
 while(i/=10);
 return n;
}

main() {
 printf("%d\n",f(10));
}
\$\endgroup\$
2
  • \$\begingroup\$ Do we define f (n) as int by default? \$\endgroup\$ Nov 25 '16 at 14:09
  • \$\begingroup\$ @MukulKumar this is standard in C, if there is no type then int is assumed. \$\endgroup\$
    – Karl Napf
    Nov 25 '16 at 17:14
1
\$\begingroup\$

Q/KDB+ 41 Bytes

sum{:"I"$string x}over'string prd 1+til n

Breakdown:

string prd 1+til n

Get the product from 1 to n

{:"I"$string x}

Function that accepts a string x and returns it converted to an integer.

over'

Iterate over the argument to it's right to the function on the left, passing each item in individually.

sum

Sum up the numbers output by the function at the end.

\$\endgroup\$
1
\$\begingroup\$

PHP, 44 bytes

<?=array_sum(str_split(gmp_fact($argv[1])));

Well it's not clever, but it works. That said it turned out better than I thought (I thought I'd need to use gmp_strval() too).

\$\endgroup\$
1
\$\begingroup\$

Pyke, 3 bytes (old version)

SBs

Explanation:

SB  -  product(range(1, input+1))
  s - digit_sum(^)
\$\endgroup\$
1
\$\begingroup\$

Groovy, 61 bytes

{"${(1..it).inject{i,r->i*r}}".collect{0.parseInt(it)}.sum()​}​

Groovy doesn't even have factorial built-ins.

"${(1..it).inject{i,r->i*r}}" - Compute factorial as string.

.collect{0.parseInt(it)} - Turn the string into an array of integers.

.sum()​ - Sum 'em.

\$\endgroup\$
1
\$\begingroup\$

Wonder, 22 bytes

@sum <>""prod rng1+1#0

This only works for inputs <= 21.

Usage:

(@sum <>""prod rng1+1#0)10

Explanation

Increment argument, tail-exclusive range from 1 to result, product, split over empty string, and sum.

\$\endgroup\$
1
\$\begingroup\$

F#, 80 bytes (74bytes for 32bit integer)

let rec s=function|0L->0L|y->y%10L+s(y/10L)
let g x={1L..x}|>Seq.fold (*) 1L|>s

F#, 98 bytes (96bytes for 32bit integer)

let f x=([1L..x]|>List.fold (*) 1L).ToString().ToCharArray()|>Array.fold (fun a c-> a+int(c)-48) 0

Test with

f 10L
g 10L

Thanks to ais523 for the anonymous match function and formatting help.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Hi, and welcome to the site! Your answers are actually slightly better than you thought; unless it's vital to your program, you can remove the newline at the end of a file and save a byte that way. (You can produce the nicely formatted headings we use elsewhere by starting the heading with a # sign.) Also, I think F# has the function notation for creating an anonymous match block (e.g. you can use let rec s=function|0L rather than let rec s x=match x with|0L); that should help you get your code a bit shorter. \$\endgroup\$
    – user62131
    Nov 24 '16 at 13:22
  • \$\begingroup\$ Thank you, it's the first time I saw the anonymous match. I select the functions in my code editor which told me 81 characters selected without the newline. I'm wondering if I got it wrong. \$\endgroup\$
    – CodeMonkey
    Nov 24 '16 at 13:35
1
\$\begingroup\$

C#, 119 116 Bytes

Edit: Saved 3 Bytes thanks to @TheLethalCoder

Golfed:

long F(int n){long f=1;int s=0;for(;n>1;)f*=n--;foreach(var c in f.ToString().ToList())s+=int.Parse(c+"");return s;}

Ungolfed:

public long F(int n)
{
  long f = 1;
  int s = 0;
  for (; n > 1;)
    f *= n--;
  foreach (var c in f.ToString().ToList())
    s += int.Parse(c + "");
  return s;
}

Tried both a long and an Int64 and it won't take higher than n=20, ultimately went with long because it is shorter...

Testing:

  Console.WriteLine(new DigitalSumFactorial().F(10));
  //27
  Console.WriteLine(new DigitalSumFactorial().F(19));
  //45
  Console.WriteLine(new DigitalSumFactorial().F(20));
  //54
\$\endgroup\$
4
  • \$\begingroup\$ You can compile to a Func<int, long> to save bytes, the for loop can be simplified to for (; i > 1;) and then set i = n outside the loop above and post decrement i in the loop i.e. f *= i--;. I think the ToList() isn't needed although I haven't tried it and you will need to add using System.Linq; into the byte count for the ForEach part \$\endgroup\$ Nov 24 '16 at 15:53
  • \$\begingroup\$ int.Parse(c+"") can be replaced with c-30 I think... \$\endgroup\$ Nov 24 '16 at 16:18
  • \$\begingroup\$ Its 48 not 30 I read the hex code by accident, also you can't remove the ToList, putting all of that together is 113 bytes including the 18 for the using statement: using System.Linq;n=>{long f=1;int s=0,i=n;for(;i>1;)f*=i--;f.ToString().ToList().ForEach(c=>s+=c-48);return s;}; \$\endgroup\$ Nov 24 '16 at 16:27
  • \$\begingroup\$ @TheLethalCoder Thanks for the tips :) I've had another play around with it and saved 3 Bytes :) \$\endgroup\$
    – Pete Arden
    Nov 24 '16 at 18:11
1
\$\begingroup\$

Lithp, 73 bytes

#N::((sum (map (split (+ "" (prod (seq 1 N))) "") #C::((- (asc C) 48)))))

I'm not sure if I should be counting import calls. Here is how you would use the above snippet:

(
    (import "lists")
    (def f #N::((sum (map (split (+ "" (prod (seq 1 N))) "") #C::((- (asc C) 48))))))
    (print (f 10))
)

It works by calculating the factorial using prod/1, converts it to a string by doing (+ "" value), splits and maps the string to get the numeric value of each number (ASCII code - 48.) Lastly, we sum/1 the resulting list.

\$\endgroup\$
1
\$\begingroup\$

Pyt, 3 2 bytes

Explanation:

        Implicit input
!       Get factorial
 Ś      Sum the digits

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, 3 bytes

Êìx

Try it

Get the factorial, split to a digit array and reduce by addition.

\$\endgroup\$
1
\$\begingroup\$

Tcl, 78 bytes

proc S n {proc F n {expr $n?($n)*\[F $n-1]:1}
expr [join [split [F $n] ""] +]}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

K (ngn/k), 10 bytes

Solution:

+/10\*/1+!

Try it online!

Explanation to follow.

\$\endgroup\$
1
\$\begingroup\$

Java 10, 70 bytes

A lambda from long to int. Breaks for input over 20.

n->{var f=n;while(n>1)f*=--n;return(f+"").chars().map(c->c-48).sum();}

Try It Online

Java 10, 163 bytes

Fully arbitrary precision. A lambda from BigInteger to BigInteger.

n->{var i=n;var f=n;while(n.compareTo(n.ONE)>0)f=f.multiply(n=n.subtract(n.ONE));return(f+"").chars().mapToObj(c->i.valueOf(c-48)).reduce(n.ZERO,(a,b)->a.add(b));}

Try It Online

Ungolfed

n -> {
    var i = n;
    var f = n;
    while (n.compareTo(n.ONE) > 0)
        f = f.multiply(n = n.subtract(n.ONE));
    return (f + "").chars()
        .mapToObj(c -> i.valueOf(c - 48))
        .reduce(n.ZERO, (a, b) -> a.add(b))
    ;
}
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -MList::Util=sum -MMath::BigInt -p, 43 bytes

Supports arbitrarily large factorials.

$_=sum(Math::BigInt->new($_)->bfac()=~/./g)

Try it online!

Perl 5 -MList::Util=sum,product -p, 27 bytes

Cannot handle extremely large factorials due to overflow.

$_=product 1..$_;$_=sum/./g

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Scala, 30 bytes

1.to(_).product+""map(_-48)sum

Try it online!

And a 34 byte solution without postfix syntax:

x=>(""+1.to(x).product:\0)(_+_-48)

Try it in Scastie

\$\endgroup\$
0
\$\begingroup\$

Java8 - 112 Chars

(First time here...)

String.valueOf(LongStream.rangeClosed(2,i).reduce(1,(a,b)->a*b)).chars().map(Character::getNumericValue).sum();
\$\endgroup\$
0
\$\begingroup\$

Julia 0.6, 25 bytes

Julia functions are generic across input types, and generate optimized code for each combination of input types. This function works with machine sized integers or arbitrary precision integers depending on the type of the argument. eg

f(10) = 27
f(50) = -97 # overflowed
f(big(50)) = 216 # no overflow, but slower due to use of BigInt
x->sum(digits(prod(1:x)))

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Clojure, 65 bytes

(fn[i](apply +(map #(-(int %)48)(str(apply *(range 1(inc i)))))))

Straightforward, character \0 has integer value of 48.

Easier to follow steps:

(defn f [i] (->> i inc (range 1) (apply *) str (map #(- (int %) (int \0)) (apply +)))
\$\endgroup\$
0
\$\begingroup\$

Pari/GP, 16 bytes

n->sumdigits(n!)

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python 3, 66 bytes

import math;print(sum(map(int,str(math.factorial(int(input()))))))

It gets factorial of number, splits it into an array, then prints it!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ Jul 7 '18 at 13:02
0
\$\begingroup\$

MATL, 9 bytes

:p[]&V!Us

Try it online!

MATL port of Stewie Griffin's Octave answer. Works up to n=22, same as the Octave and R answers.

:p - factorial.
[]&V - string representation of the number, fully expanded (without the []&, larger numbers use the scientific notation which won't do for our purposes).
!U transpose and convert back to numbers, getting individual digits.
s - sum those digits.

The []& part can be removed for -3 bytes, but then the range is further limited to only work up to 17, instead of 22.

I could stretch the input range to 23 with a couple of tricks, but that costs an additional 20 bytes:

:1w5X2Y%"@*t10\~?10/]][]&V!Us

(basically, use the uint64 data type instead of the usual double, multiply by each number upto the given number, but divide away 10 whenever our product is divisible by it (since trailing zeros add nothing to the digit sum).)

That seems to be as far as we can go with MATLAB/MATL without doing an ad-hoc implementation of bignum in the program.

\$\endgroup\$
0
\$\begingroup\$

Vyxal, 2 bytes

‼∑

Try it Online!

A very literal interpretation of the challenge: sum_of_digits_of(factorial(input))

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.