5
\$\begingroup\$

In light of today's date...

A factorial of a number n, is the product of all the numbers from 1 to n inclusive.

The Challenge

Given an integer n where 0 <= n <= 420, find the sum of the digits of n!. It's that simple :P

Notes: I feel like this challenge isn't too simple, as some languages have a very hard time storing numbers that are fairly large. Also, coding a BigInteger datatype is fairly straightforward, but hard to golf.


Examples

Input: 100. Output: 648.

Input: 200. Output: 1404.

Input: 420. Output: 3672.


Scoring

  • The input and output can be given by any convenient method.
  • Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
  • Standard loopholes are forbidden.
  • This is so all usual golfing rules apply, and the shortest code (in bytes) wins.

EDIT: Ok, I guess it's actually easy...take a look at the Jelly answer below. Anyways, I guess we all know which one's going to be accepted. But, I'd still like to see some interesting ideas and tricks to this problem!

\$\endgroup\$
11
  • 1
    \$\begingroup\$ This is A004152 in the OEIS. \$\endgroup\$
    – Giuseppe
    Commented Apr 21, 2018 at 1:56
  • 5
    \$\begingroup\$ @NL628: Typically, people are trying to get the smallest byte count for a particular language. So yes, Jelly in this case has very short result; but that hardly makes the results for other languages less fun or interesting for most afficianados of PPCG! \$\endgroup\$
    – Chas Brown
    Commented Apr 21, 2018 at 2:03
  • 1
    \$\begingroup\$ I'd like this better without the arbitrary restriction of 42<=n<=420 \$\endgroup\$
    – Jo King
    Commented Apr 21, 2018 at 3:03
  • 2
    \$\begingroup\$ Today is Apr 21 for me. Nothing special. \$\endgroup\$
    – user202729
    Commented Apr 21, 2018 at 4:00
  • 6
    \$\begingroup\$ @JoKing The lower bound doesn't make much sense, but having an explicit upper bound (up to which all submissions must work, regardless of native types) is a good thing. \$\endgroup\$
    – Dennis
    Commented Apr 21, 2018 at 13:57

27 Answers 27

5
\$\begingroup\$

(old problem) JavaScript (Node.js), 99 94 92 88 86 83 80 78 bytes

f=(x,t=[...21+Array(999)])=>x?f(s=x-1,t.map(d=>-s+(s+=(t=~~d*x+t/10|0)%10))):s

Try it online!

well, first language without large number support

Thank Arnauld for 4 bytes

f = (x, t = ['2', '1', ...','.repeat(998)]) => // init x, t=1
  x ?
    f( // recursive x':=x-1, t'=t*x
      s = x-1, // s init to 0 when x==1, in next recursion just return
      t.map (
        b = // init b to NaN
        d =>
          -s + ( //  to return the added value
            s+= ( // -s + (s + k) == k
              b=
                ~~d*x+b/10 | 0
                // ~~d converts ',' to 0
                // b is initally NaN, after first iteration
                // it's zero, then the last digit sum result with carry
            ) % 10
          )
      )
    )
:
  s // the sum from x==1
\$\endgroup\$
4
  • 1
    \$\begingroup\$ ps. it doesn't work for 0, but the original question says >=42 \$\endgroup\$
    – l4m2
    Commented Apr 22, 2018 at 12:40
  • \$\begingroup\$ Umm no, it says <= 420 ... \$\endgroup\$
    – Adi219
    Commented Apr 22, 2018 at 12:50
  • 1
    \$\begingroup\$ First version "Given an integer n where 42 <= n <= 420, find the sum of the digits of n!" \$\endgroup\$
    – l4m2
    Commented Apr 22, 2018 at 13:27
  • \$\begingroup\$ Nice this is what I was looking for...a language that doesn't have the capability of storing massive amounts of digits. Could you explain how it works? \$\endgroup\$
    – NL628
    Commented Apr 22, 2018 at 17:25
4
\$\begingroup\$

Neim, 2 bytes

𝐓𝐬

Explanation: Factorial 𝐓; sum 𝐬.

This outgolfs 3-byte answers as the sum command is able to implicitly convert to a list.

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Wolfram Language (Mathematica), 24 bytes

Total@IntegerDigits[#!]&

Try it online!

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 3 bytes

!SO

Try it online!

Explanation

!     # factorial of input
 S    # split to list of digits
  O   # sum
\$\endgroup\$
1
  • \$\begingroup\$ I really think O on a string/non-list should be digit sum. It's come up enough in these non-important challenges. \$\endgroup\$ Commented Apr 23, 2018 at 0:04
4
\$\begingroup\$

Haskell, 42 40 38 bytes

f n=sum[read[d]|d<-show$product[1..n]]

Try it online!

Thanks to @Laikoni for saving 2 bytes with list comprehension.

\$\endgroup\$
1
  • \$\begingroup\$ 38 bytes: f n=sum[read[d]|d<-show$product[1..n]]. \$\endgroup\$
    – Laikoni
    Commented Apr 21, 2018 at 7:52
3
\$\begingroup\$

Attache, 11 bytes

Sum@List@`!

Try it online!

Sums the List of digits in the factorial (!) of the input. Anonymous function.

\$\endgroup\$
3
\$\begingroup\$

Pari/GP, 16 bytes

n->sumdigits(n!)

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ When evaluated on 42000000, gives 1311426180 (takes under three minutes on my machine). The number has 310,936,107 digits. The average contribution per digit is 4.34, a bit under the "ideal" 4.5, which is likely related to the long string of zero digits in the end. \$\endgroup\$ Commented Apr 21, 2018 at 16:19
3
\$\begingroup\$

J, 13 11bytes

1#.,.&.":@!

Try it online!

Explanation:

! calculate the factorial

@ and

,.&.": convert it to a list of digits (convert to string ":, ravel ,. and convert each char back to number)

1#. find their sum by base-1 conversion

\$\endgroup\$
3
\$\begingroup\$

Perl 6, 21 bytes

{[*](2..$_).comb.sum}

Try it

Expanded:

{  # bare block lambda with implicit parameter 「$_」

  [*](       # reduce using &infix:« * »

    2 .. $_  # Range starting at 2 (slight optimization over 1)

  ).comb     # split the result into digits
  .sum       # find the sum of those digits
}
\$\endgroup\$
3
\$\begingroup\$

R + gmp, 66 bytes

sum(strtoi(el(strsplit(paste(gamma(gmp::as.bigz(scan())+1)),""))))

Try it online!

gmp is one of the several BigInteger packages available on CRAN.

\$\endgroup\$
1
  • \$\begingroup\$ sum(utf8ToInt(as.character(gmp::factorialZ(scan())))-48) should do the trick as well \$\endgroup\$
    – MickyT
    Commented Apr 22, 2018 at 20:24
3
\$\begingroup\$

Python 2, 51 bytes

f=lambda L,p=1:0**L*sum(map(eval,`p`))or f(L-1,p*L)

Try it online!

We'd like to write map(int,`p`), but since repr(p) might have a trailing L, that won't work.

Ordinarily, we'd resort to map(int,str(p)) and lose three bytes.

Here, can we name our counting-down variable L, and write map(eval,`p`). Since L is 0 when we compute the result, the digit sum is unaffected.

\$\endgroup\$
2
\$\begingroup\$

Jelly, 3 bytes

!DS

Try it online!

!DS        - main link, taking an integer  e.g. 9
!          - factorial                     -->  362880
 D         - convert to decimal            -->  [3,6,2,8,8,0]
  S        - sum of list                   -->  27
\$\endgroup\$
3
  • \$\begingroup\$ ...you can't be serious... \$\endgroup\$
    – NL628
    Commented Apr 21, 2018 at 1:42
  • \$\begingroup\$ DENNIS WHAT DID YOU DO \$\endgroup\$
    – NL628
    Commented Apr 21, 2018 at 1:43
  • 1
    \$\begingroup\$ @NL628 Python 3 has bigint support, Jelly inherits that. \$\endgroup\$
    – user202729
    Commented Apr 21, 2018 at 3:31
2
\$\begingroup\$

Pyt, 2 bytes

Try it online!

Explanation:

      Implicit input
!     Factorial
Ś     Sum of digits
      Implicit output
\$\endgroup\$
2
\$\begingroup\$

Python 2, 52 54 52 bytes

f=lambda n,r=1:1/n*sum(map(int,str(r)))or f(n-1,n*r)

Try it online!

-2 bytes thx to Kirill L.

\$\endgroup\$
6
  • \$\begingroup\$ Could you tell me how to make this challenger harder? I'm kind of struggling right now... \$\endgroup\$
    – NL628
    Commented Apr 21, 2018 at 1:49
  • 1
    \$\begingroup\$ I believe you need the f= as this is a recursive lambda \$\endgroup\$
    – Giuseppe
    Commented Apr 21, 2018 at 1:57
  • 1
    \$\begingroup\$ @Giuseppe: Quite right! Thx. \$\endgroup\$
    – Chas Brown
    Commented Apr 21, 2018 at 2:01
  • 4
    \$\begingroup\$ @NL628 don't make the challenge harder after posting it. That said, if you're looking for some hard challenges for the future, look into mathematical subjects like graph theory, or sets. \$\endgroup\$ Commented Apr 21, 2018 at 2:04
  • \$\begingroup\$ @NL628 Also, you can post it to the Sandbox where it can be refined before posting it to main. \$\endgroup\$
    – Jo King
    Commented Apr 21, 2018 at 9:05
2
\$\begingroup\$

Octave with Symbolic Package, 43 42 bytes

@(s)sum(char(sym(['factorial(' s 41]))-48)

Anonymous function that takes the input as a string and outputs a nubmer.

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Bash + GNU utilities, 36

  • 6 bytes saved thanks to @Cowsquack
seq -s* $1|bc|sed 's/\B\|\\/+&/g'|bc

Try it online!

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

Charcoal, 7 bytes

IΣΠ…¹⊕N

Try it online! Link is to verbose version of code. Explanation:

      N Input as a number
     ⊕  Increment
    ¹   Literal 1
   …    Range
  Π     Product
 Σ      Sum (of digits)
I       Cast to string
        Implicitly print

InclusiveRange(1, InputNumber()) also works but the explanation is prettier this way.

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

Elixir, 54 bytes

fn n->Enum.sum Integer.digits Enum.reduce 1..n,&*/2end

Try it online!

Ungolfed:

def sum_factorial(n) do
  # factorial
  Enum.reduce(1..n, fn(x, acc) -> x * acc end)
  # sum digits
  |> Integer.digits
  |> Enum.sum
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 107 bytes

f(x){int a[999]={1},i,c;
for(;x;--x)for(c=i=0;i<999;)c=(a[i]=a[i]*x+c)/10,a[i++]%=10;
for(;i--;)x+=a[i];
i=x;}

Try it online!

\$\endgroup\$
7
  • \$\begingroup\$ a[i++]%=10 into the for \$\endgroup\$
    – l4m2
    Commented Apr 21, 2018 at 12:48
  • \$\begingroup\$ c;f(x){int a[999]={1},i;for(;x;--x)for(i=0;i<999;a[i++]%=10)c=(a[i]=a[i]*x+c)/10;for(;i--;)x+=a[i];i=x;} \$\endgroup\$
    – l4m2
    Commented Apr 21, 2018 at 12:51
  • \$\begingroup\$ c;i;f(x){int a[999]={x},n;for(;--x;)for(i=n=0;i<999;n+=a[i++]%=10)c=(a[i]=a[i]*x+c)/10;i=n;} \$\endgroup\$
    – l4m2
    Commented Apr 21, 2018 at 12:54
  • 2
    \$\begingroup\$ 104 bytes \$\endgroup\$
    – gastropner
    Commented Apr 21, 2018 at 12:57
  • \$\begingroup\$ @l4m2 why the i=n part then? c;n;f(x){int a[999]={x},i;for(;--x;)for(i=n=0;i<999;n+=a[i++]%=10)c=(a[i]=a[i]*x+c)/10;} Though fails for x=0 now that the lower bound has been edited out of the challenge. \$\endgroup\$ Commented Apr 23, 2018 at 1:56
1
\$\begingroup\$

Husk, 3 bytes

ΣdΠ

Try it online!

Explanation

ΣdΠ  Implicit input
  Π  Factorial
 d   Convert to list of digits
Σ    Sum
\$\endgroup\$
1
\$\begingroup\$

Ruby, 33 bytes

->n{(2..n).inject(:*).digits.sum}

Try it online!

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

Stax, 4 bytes

║▼⌡è

Run and debug it at staxlang.xyz!

Unpacked (5 bytes) and explanation

|FE|+
|F       Implicit input. Factorial.
  E      Array of decimal digits.
   |+    Sum of list. Implicit print.
\$\endgroup\$
1
\$\begingroup\$

Python, 75 bytes

import math
print(sum(map(int,list(str(math.factorial(int(input())))))))
\$\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\$
0
\$\begingroup\$

Java 10, 135 bytes

n->{var r=java.math.BigInteger.ONE;for(;!n.equals(r.ZERO);n=n.subtract(r.ONE))r=r.multiply(n);return(r+"").chars().map(c->c-48).sum();}

Explanation:

Try it online.

n->{                         // Method with BigInteger parameter and integer return-type
  var r=java.math.BigInteger.ONE;
                             //  BigInteger, starting at 1
  for(;!n.equals(r.ZERO);    //  Loop as long as `n` is not 0 yet
      n=n.subtract(r.ONE))   //    After every iteration: subtract 1 from `n`
    r=r.multiply(n);         //   Multiply `r` by `n`
  return(r+"").chars()       //  Loop over the characters of `r`
              .map(c->c-48)  //   Convert them to digits
              .sum();}       //   And return the sum of those digits
\$\endgroup\$
0
\$\begingroup\$

Ceylon, 98 bytes

import ceylon.whole{l=one}Integer q(Integer n)=>sum({0,*product({l,*(l:n)}).string*.offset('0')});

Try it online

Explanation:

This is quite long, because we need to convince the compiler that we are not doing bogus stuff.

import ceylon.whole { l = one } // 1

Integer q(Integer n) => // 2
    sum({0,*product({l,*(l:n)}).string *.offset('0')});
//  |   |   |       |    '3' || |    | | |         |||
//  |   |   |       '--4-----'| |    | 7 |         ||| 
//  |   |   '----5------------' '-6--'   '--8------'||
//  |   |   '----------------9---------------------'||
//  |   '----------------10-------------------------'|
//  '------------------------11----------------------'
  1. Import the value one from the package ceylon.whole, and give it locally the name l (small L, not the digit 1 – though I choose this alias for its similarity to 1). (This alias import costs two bytes here, but saves two bytes for each of the two usages).
  2. Define a function q from Integer to Integer, which maps each parameter n to the result of the following expression (calculated in steps 3 to 11). Top-level functions always need a type declaration. For local ones we could replace the return type by function, which wouldn't have saved anything here. (For inline functions, we sometimes can omit both types and the keyword, if they can be inferred from context.)
  3. This is a short syntax for measure(one, n), which returns either the empty sequence [] if n is non-positive, or a Range<Whole> starting from one and having size n (i.e. all numbers from 1 to n, assuming n is a positive integer). Type: []|Range<Whole>, which is a subtype of {Whole*} (possibly empty iterable of Whole).
  4. This is an iterable enumeration, with one as the first element and then all the elements of one:n (the * here expands the iterable). This has type {Whole+}, and has the only purpose to make sure the compiler knows it is non-empty. We could have used [...] instead of {...} for a tuple enumeration (which is non-lazy). No difference here apart from performance. We could have written this (l:n).follow(l), but that is longer.
  5. Calculate the product of all those numbers, type Whole. product needs a non-empty iterable as a parameter to work (as the product of nothing is not defineable in a type-independent way).
  6. Get the string representation of the result of step 5. (The .string attribute exists for all classes, and Whole implements it in the expected way, using decimal digits.) – type String, which is also a {Character*} (possibly empty iterable of characters).
  7. The *. operator for iterables applies the the following attribute or method call to each element of the iterable and collects the result in a sequence. It can be seen as syntactic sugar for .collect(c => c.offset('0')). This is non-lazily evaluated, there is also .map(...) which is lazy.
  8. The offset method of Character just calculates the difference between the unicode code points, returning an Integer. This takes advantage of the fact that the ten decimal digits are sequential starting with 0 in ASCII (and thus unicode).
  9. This whole thing has now type [Integer*] (possibly empty sequence of integers – because the string is possibly empty for the compiler).
  10. Same trick again as step 4, we make it an {Integer+} (nonempty iterable) by prepending a 0 (which has no effect on the following sum).
  11. Sum it all up.
\$\endgroup\$
0
\$\begingroup\$

CJam, 11 8 bytes

there is in fact a better way to get a list of digits

lim!Ab:+

Try it online!

Explanation:

li          input, convert to integer
  m!        factorial
    Ab      convert to array of digits in base 10
      :+    sum

Original solution:

lim!`1/:i:+

Explanation:

li              input converted to integer
  m!            factorial
    `           convert to string
     1/         split into pieces of length 1
       :i       convert back to integer
         :+     sum
\$\endgroup\$

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