25
\$\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\$
  • \$\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
  • 1
    \$\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

49 Answers 49

1
2
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.

| improve this answer | |
\$\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).

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Pyke, 3 bytes (old version)

SBs

Explanation:

SB  -  product(range(1, input+1))
  s - digit_sum(^)
| improve this answer | |
\$\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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
  • 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
| improve this answer | |
\$\endgroup\$
  • \$\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\$ – TheLethalCoder Nov 24 '16 at 15:53
  • \$\begingroup\$ int.Parse(c+"") can be replaced with c-30 I think... \$\endgroup\$ – TheLethalCoder 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\$ – TheLethalCoder 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.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Japt, 3 bytes

Êìx

Try it

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

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

K (ngn/k), 10 bytes

Solution:

+/10\*/1+!

Try it online!

Explanation to follow.

| improve this answer | |
\$\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();
| improve this answer | |
\$\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!

| improve this answer | |
\$\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 +)))
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Pyt, 3 2 bytes

Explanation:

        Implicit input
!       Get factorial
 Ś      Sum the digits

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Pari/GP, 16 bytes

n->sumdigits(n!)

Try it online!

| improve this answer | |
\$\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!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Jonathan Frech 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.

| improve this answer | |
\$\endgroup\$
0
\$\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))
    ;
}
| improve this answer | |
\$\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.