Suma de dígitos factoriales


25

El desafío es calcular la suma de dígitos del factorial de un número.


Ejemplo

Input: 10
Output: 27

10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, y la suma de los dígitos en el número 10! es 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27

Puede esperar que la entrada sea un número entero superior a 0. La salida puede ser de cualquier tipo, pero la respuesta debe estar en la base estándar del lenguaje de codificación.


Casos de prueba:

10    27
19    45
469   4140
985   10053

Nota: algunos idiomas no pueden admitir grandes números por encima de enteros de 32 bits; para esos idiomas no se espera que calcule factoriales grandes.

Enlace OEIS aquí gracias a Martin Ender


Este es el , por lo que gana el código más corto en caracteres.


¿Cuál es el número máximo de entrada que puede esperar? Con números enteros de 32 bits en R, este desafío no puede resolverse con precisión en el pasadon>21
Billywob

1
@Billywob Para R, entonces solo necesitarás ir a 20. Editaré la pregunta para reflejar esto
george

Respuestas:





7

C ++ 11, 58 bytes

Como lambda sin nombre modificando su entrada:

[](int&n){int i=n;while(--n)i*=n;do n+=i%10;while(i/=10);}

Uno de los raros casos en que mi código C ++ es más corto que el código C .

Si desea admitir casos más grandes, cambie a C ++ 14 y use:

[](auto&n){auto i=n;while(--n)i*=n;do n+=i%10;while(i/=10);}

y proporcione el argumento de llamada con ullsufijo.

Uso:

auto f=
[](int&n){int i=n;while(--n)i*=n;do n+=i%10;while(i/=10);}
;

main() {
  int n=10;
  f(n);
  printf("%d\n",n);
}

7

Ruby, 63 61 53 38 bytes

Nuevo enfoque gracias a manatwork:

->n{eval"#{(1..n).reduce:*}".chars*?+}

Antiguo:

->n{(1..n).reduce(:*).to_s.chars.map(&:hex).reduce:+}
  • -3 bytes gracias a Martin Ender
  • -5 bytes gracias a GB

1
La vieja y aburrida evalmanera: ->n{eval"#{(1..n).reduce:*}".chars*?+}.
manatwork

6

Pyth, 7 6 bytes

Gracias a @Kade por salvarme un byte

sj.!QT

Pruébalo en línea!

Esta es la primera vez que uso Pyth, así que estoy seguro de que mi respuesta podría ser bastante útil.

Explicación:

s Sum
  j the digits of
    .! the factorial of
      Q the input
    T in base 10

1
10está asignado a una variable T, por lo que puede hacer esto sj.!QT:)
Kade

¡Vale gracias! Lo
agregaré

¡Agradable! ssM`.!también hace el trabajo, también en 6 bytes.
hakr14

5

Haskell, 41 40 bytes

f x=sum$read.pure<$>(show$product[1..x])

Ejemplo de uso: f 985-> 10053.

Haga una lista de 1a x, calcule el producto de los elementos de la lista, conviértalo en su representación de cadena, convierta cada carácter en un número y sume.

Editar: @Angs guardó un byte. ¡Gracias!


f x=sum$read.pure<$>(show$product[1..x])ahorra un byte
Angs

5

Python, 54 bytes

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

repl.it


Acabo de llegar con una versión ligeramente peor de este que se ve manera muy similar para que sea una respuesta por separado. Bravo
osuka_

5

R, 58 53 bytes

Editar: guardado un byte gracias a @Jonathan Carroll y un par de gracias a @Micky T

sum(as.double(el(strsplit(c(prod(1:scan()),""),""))))

Desafortunadamente, con enteros de 32 bits, esto solo funciona n < 22. Toma entradas de stdin y salidas a stdout.

Si a uno le gustaría una precisión de nivel superior, tendría que usar alguna biblioteca externa como Rmpfr:

sum(as.numeric(el(strsplit(paste(factorial(Rmpfr::mpfr(scan()))),""))))

1
Llegué exactamente la misma respuesta que es así, entonces encontré una ganancia de 1 byte en c(x,"")contra paste(x): sum(as.integer(el(strsplit(c(factorial(scan()),""),"")))). Obliga el resultado factorial al carácter y lo strsplitdevuelve como una segunda lista, por lo que elaún funciona y extrae los primeros elementos de la lista.
Jonathan Carroll

2
¿qué tal prod(1:scan())?
MickyT

1
también as.double debería ser suficiente
MickyT

@MickyT ¡Gracias! Actualizado.
Billywob

strtoifunciona como un reemplazo más corto as.double, creo.
Giuseppe

4

Pip , 8 bytes

$+$*++,a

Pruébalo en línea!

Explicación

      ,a    # range
    ++      # increment
  $*        # fold multiplication
$+          # fold sum

Lo siento, en realidad logré publicar una respuesta 05AB1E antes que tú;).
Urna mágica de pulpo

2
@carusocomputing: Jeje. Me dio la oportunidad de buscar un nuevo idioma :)
Emigna

1
Creo que eres el primero además de mí en usar Pip para una respuesta de golf de código no políglota. : D
DLosc


3

Brachylog , 5 bytes

$!@e+

Pruébalo en línea!

Explicación

Básicamente el algoritmo descrito:

$!       Take the factorial of the Input
  @e     Take the elements of this factorial (i.e. its digits)
    +    Output is the sum of those elements

3

Java 7, 148 bytes

int s=1,ret=0;while(i>1){s=s*i; i--;}String y=String.valueOf(s);for(int j=0;j<y.length();j++){ret+=Integer.parseInt(y.substring(j,j+1));}return ret;

@EyalLev No hay límite especificado en la pregunta. ¿Cómo espera manejar por mucho tiempo un factorial que equivale a más de 9,223,372,036,854,775,807?
jacksonecac

3

Ruby, 63 60 53 51 bytes

->n{a=0;f=(1..n).reduce:*;f.times{a+=f%10;f/=10};a}

Gracias a Martin por la ayuda en el golf.


3

Pushy , 4 bytes

fsS#

Dar entrada en la línea de comandos: $ pushy facsum.pshy 5. Aquí está el desglose:

f      % Factorial of input
 s     % Split into digits
  S    % Push sum of stack
   #   % Output

3

Octava, 30 bytes

@(n)sum(num2str(prod(1:n))-48)

Calcula el factorial tomando el producto de la lista [1 2 ... n]. Lo convierte en una cadena y lo resta 48de todos los elementos (código ASCII para 0). Finalmente lo resume :)


3

bash (seq, bc, fold, jq), 34 33 bytes

Seguramente no sea el más elegante pero para el desafío

seq -s\* $1|bc|fold -1|jq -s add

fold -1guarda un byte.
Trauma digital

@DigitalTrauma corregido! gracias
Adam

3

C, 58 bytes

Esto no es perfecto Solo funciona porque tiene que ser -1 en el inicio. La idea es usar dos funciones recursivas en una función. No fue tan fácil como pensé al principio.

a=-1;k(i){a=a<0?i-1:a;return a?k(i*a--):i?i%10+k(i/10):0;}

Uso y formato comprensible:

a = -1;
k(i){
   a = a<0 ? i-1 : a;
   return a ? k(i*a--) : i? i%10+k(i/10) :0;
}

main() {
   printf("%d\n",k(10));
}

Editar: Encontré un método que permite usar esta función varias veces, pero luego la longitud es de 62 bytes.

a,b;k(i){a=b?a:i+(--b);return a?k(i*a--):i?i%10+k(i/10):++b;}

Buena idea, pero no entiendo por qué no sería más corto usar una función para devolver el factorial y otra para calcular la suma de dígitos, como a (b (10)). ¿Es la palabra "retorno" demasiado larga para que eso funcione?
JollyJoker

Regreso come mucho. Lo intento, por supuesto. Tal vez alguien puede hacerlo por lo menos no pude conseguir que el trabajo
teksturi

1
podría aceptar dos argumentos para guardar algunos bytes: codegolf.stackexchange.com/a/153132/77415
user84207

3

Perl 6 , 21 bytes

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

Expandido:

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

  [+]           # reduce the following with 「&infix:<+>」

    [*](        # reduce with 「&infix:<*>」
      2 .. $_   # a Range that include the numbers from 2 to the input (inclusive)
    ).comb      # split the product into digits
}

Felicidades, tienes la respuesta no. 101010!
RudolfJelin

@ RudolfL.Jelínek Eso no es nada, en StackOverflow y Meta.StackExchange Soy el usuario número 1337
Brad Gilbert b2gills

3

Cubix, 33 32 bytes

u*.$s.!(.01I^<W%NW!;<,;;q+p@Opus

Forma neta:

      u * .
      $ s .
      ! ( .
0 1 I ^ < W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
      . . .
      . . .
      . . .

Pruébalo en línea!

Notas

  • Funciona con entradas de hasta 170 inclusive, las entradas más altas dan como resultado un bucle infinito, porque su factorial produce Infinity número (técnicamente hablando, es una propiedad no escribible, no enumerable y no configurable del objeto de ventana).
  • La precisión se pierde para las entradas 19 y superiores, porque los números superiores a 2 53 (= 9 007 199 254 740 992) no se pueden almacenar con precisión en JavaScript.

Explicación

Este programa consta de dos bucles. El primero calcula el factorial de la entrada, el otro divide el resultado en sus dígitos y los suma. Luego se imprime la suma y finaliza el programa.

comienzo

Primero, necesitamos preparar la pila. Para esa parte, usamos las primeras tres instrucciones. La IP comienza en la cuarta línea, apuntando hacia el este. La pila está vacía.

      . . .
      . . .
      . . .
0 1 I . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
      . . .
      . . .
      . . .

Mantendremos la suma en la parte inferior de la pila, por lo que debemos comenzar 0siendo la suma almacenando eso en la parte inferior de la pila. Luego, debemos presionar a 1, porque la entrada se multiplicará inicialmente por el número anterior. Si esto fuera cero, el factorial siempre daría cero también. Por último, leemos la entrada como un entero.

Ahora, la pila está [0, 1, input]y la IP está en la cuarta línea, la cuarta columna, apuntando hacia el este.

Bucle factorial

Este es un bucle simple que multiplica los dos elementos superiores de la pila (el resultado del bucle anterior y la entrada - n, y luego disminuye la entrada. Se rompe cuando la entrada llega a 0. La $instrucción hace que la IP omita el u- gire. El bucle es la siguiente parte del cubo. La IP comienza en la cuarta línea, cuarta columna.

      u * .
      $ s .
      ! ( .
. . . ^ < . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
      . . .
      . . .
      . . .

Debido al ^carácter, la IP comienza a moverse hacia el norte de inmediato. Luego, ugira la IP y la mueve una hacia la derecha. En la parte inferior, hay otra flecha: <apunta la IP de nuevo al ^. La pila comienza como [previousresult, input-n], donde nes el número de iteraciones. Los siguientes caracteres se ejecutan en el bucle:

*s(
*   # Multiply the top two items
    #   Stack: [previousresult, input-n, newresult]
 s  # Swap the top two items
    #   Stack: [previousresult, newresult, input-n]
  ( # Decrement the top item
    #   Stack: [previousresult, newresult, input-n-1]

Luego, la parte superior de la pila (entrada disminuida) se compara 0con la !instrucción, y si es así 0, use omite el carácter.

Suma los dígitos

La IP se envuelve alrededor del cubo, terminando en el último carácter en la cuarta línea, inicialmente apuntando hacia el oeste. El siguiente bucle consta de prácticamente todos los caracteres restantes:

      . . .
      . . .
      . . .
. . . . . W % N W ! ; <
, ; ; q + p @ O p u s .
. . . . . . . . . . . .
      . . .
      . . .
      . . .

El ciclo primero elimina el elemento superior de la pila (que es 10o 0) y luego comprueba lo que queda del resultado del factorial. Si eso se ha reducido a 0, se imprime la parte inferior de la pila (la suma) y el programa se detiene. De lo contrario, se ejecutan las siguientes instrucciones (la pila comienza como[oldsum, ..., factorial] ):

N%p+q;;,s;
N          # Push 10
           #   Stack: [oldsum, ..., factorial, 10]
 %         # Push factorial % 10
           #   Stack: [oldsum, ..., factorial, 10, factorial % 10]
  p        # Take the sum to the top
           #   Stack: [..., factorial, 10, factorial % 10, oldsum]
   +       # Add top items together
           #   Stack: [..., factorial, 10, factorial % 10, oldsum, newsum]
    q      # Send that to the bottom
           #   Stack: [newsum, ..., factorial, 10, factorial % 10, oldsum]
     ;;    # Delete top two items
           #   Stack: [newsum, ..., factorial, 10]
       ,   # Integer divide top two items
           #   Stack: [newsum, ..., factorial, 10, factorial/10]
        s; # Delete the second item
           #   Stack: [newsum, ..., factorial, factorial/10]

Y el ciclo comienza de nuevo, hasta que sea factorial/10igual a 0.


3

C, 47 bytes

f(n,a){return n?f(n-1,a*n):a?a%10+f(0,a/10):0;}

uso:

f(n,a){return n?f(n-1,a*n):a?a%10+f(0,a/10):0;}
main() {
  printf("answer: %d\n",f(10,1));
}

2

Python, 57 bytes

import math
lambda n:sum(map(int,str(math.factorial(n))))

Pruébalo en línea


¿Podrías usar garrapatas en lugar de str?
nedla2004

2
@ nedla2004 Eso agregaría una Lvez que el factorial sea lo suficientemente grande como para ser largo.
Kade

2

Lote, 112 bytes

@set/af=1,t=0
@for /l %%i in (1,1,%1)do @set/af*=%%i
:g
@set/at+=f%%10,f/=10
@if %f% gtr 0 goto g
@echo %t%

set/aFunciona convenientemente en el valor actual de una variable, por lo que funciona normalmente dentro de un bucle. Solo funciona hasta 12 debido a las limitaciones del tipo entero de Batch, por lo que en teoría podría guardar un byte suponiendo f<1e9:

@set/af=1,t=0
@for /l %%i in (1,1,%1)do @set/af*=%%i
@for /l %%i in (1,1,9)do @set/at+=f%%10,f/=10
@echo %t%

Pero de esa manera se encuentra la locura ... También podría codificar la lista en ese caso (97 bytes):

@call:l %1 1 1 2 6 6 3 9 9 9 27 27 36 27
@exit/b
:l
@for /l %%i in (1,1,%1)do @shift
@echo %2

2

JavaScript (ES6), 50 bytes

f=(n,m=1,t=0)=>n?f(n-1,n*m):m?f(n,m/10|0,t+m%10):t

Solo funciona n=22debido a limitaciones de precisión de punto flotante.


2

Befunge 93 , 56 54 bytes

Se guardaron 2 bytes para usar get en lugar de comillas. Esto me permite cambiar las 2 líneas superiores sobre 1, lo que reduce el espacio en blanco innecesario.

Pruébalo en línea!

&#:<_v#:-1
: \*$<:_^#
g::v>91+%+00
_v#<^p00</+19
@>$$.

Explicación:

&#:<                Gets an integer input (n), and reverses flow direction
&#:< _v#:-1         Pushes n through 0 onto the stack (descending order)

:  \*$<:_^#         Throws the 0 away and multiplies all the remaining numbers together

(reorganized to better show program flow):
vp00< /+19 _v#<    Stores the factorial at cell (0, 0). Pushes 3 of whatever's in
> 91+%+ 00g ::^    cell (0, 0). Pops a, and stores a / 10 at (0, 0),
                   and adds a % 10 to the sum.

@>$$.              Simply discards 2 unneeded 0s and prints the sum.

Estás en lo correcto. Estoy trabajando en una nueva versión. FYI, estoy usando quickster.com, porque otros que encontré no trataron `` correctamente cuando solo había un # en la pila.
MildlyMilquetoast

¡Gracias! Parece que este código solo funciona correctamente en la versión Befunge-98 , probablemente debido al método put.
MildlyMilquetoast

48 bytes que también maneja 0 correctamente
Jo King

2

Javascript ES6 - 61 54 Bytes

n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)

EDITAR: Gracias a Hedi y ETHproductions por reducir 7 bytes. Tendré que recordar que t - = - j truco.


1
¡Buena respuesta! Puede guardar un par de bytes de varias maneras:n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
ETHproductions

@ETHproductions Algunos bytes más se pueden guardar con eval:n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
Hedi

@Hedi lo sé, lo estaba dando un paso a la vez :-)
ETHproductions

2

AHK , 60 bytes

a=1
Loop,%1%
a*=A_Index
Loop,Parse,a
b+=A_LoopField
Send,%b%

AutoHotkey no tiene una función factorial incorporada y las funciones de bucle tienen nombres largos para sus variables incorporadas. El primer bucle es el factorial y el segundo es sumar los dígitos.


2

J, 12 11 bytes

Guardado 1 byte gracias a cole!

1#.10#.inv!

Esto simplemente aplica sum ( 1#.) a los dígitos (usando inversainv conversión de base #.con una base de 10) del factorial ( !) del argumento.

Casos de prueba

Nota: los dos últimos casos de prueba son bigints, marcados con un final x.

   f=:10#.inv!
   (,. f"0) 10 19 469x 985x
 10    27
 19    45
469  4140
985 10053

Puede usar "."0":para obtener dígitos
Bolce Bussiere

11 bytes: 1#.,.&.":@!que también requiere precisión extendida para casos más pequeños (no estoy seguro de por qué). También 11 bytes: 1#.10#.inv!.
cole


1

C, 63 60 bytes

-3 byte para do...whilebucle.

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

Sin golf y uso:

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

main() {
 printf("%d\n",f(10));
}

¿Definimos f (n) como intpor defecto?
Mukul Kumar el

@MukulKumar esto es estándar en C, si no hay ningún tipo, entonces intse supone.
Karl Napf
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.