Soma de dígitos fatoriais

25

O desafio é calcular a soma dos dígitos do fatorial de um número.


Exemplo

Input: 10
Output: 27

10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800 e a soma dos dígitos no número 10! é 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27

Você pode esperar que a entrada seja um número inteiro acima de 0. A saída pode ser de qualquer tipo, mas a resposta deve estar na base padrão da linguagem de codificação.


Casos de teste:

10    27
19    45
469   4140
985   10053

Nota: alguns idiomas não podem suportar números grandes acima de números inteiros de 32 bits; para esses idiomas, não é esperado que você calcule fatoriais grandes.

Link OEIS aqui, graças a Martin Ender


Isso é , então o código mais curto em caracteres vence!

George
fonte
Qual é o número máximo de entrada esperado? Com inteiros de 32 bits em R este desafio não pode ser resolvido com precisão passadon>21
Billywob
1
@Billywob Para R então você só precisa ir para 20. Vou editar questão para refletir essa
george

Respostas:

11

Gelatina , 3 bytes

!DS

Experimente online!

Faz o que você espera:

!    Factorial.
 D   Decimal digits.
  S  Sum.
Martin Ender
fonte
8

Mathematica, 21 bytes

Tr@IntegerDigits[#!]&
Martin Ender
fonte
4
veio aqui para digitar esses caracteres exatos.
Michael Stern
Por que [#!]e não @#!? (Mathematica noob)
Cyoce
1
@Cyoce porque @tem maior precedência que !.
Martin Ender
7

C ++ 11, 58 bytes

Como lambda sem nome, modificando sua entrada:

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

Um dos casos raros em que meu código C ++ é mais curto que o código C .

Se você deseja dar suporte a casos maiores, mude para C ++ 14 e use:

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

e forneça o argumento de chamada com ullsufixo.

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);
}
Karl Napf
fonte
7

Ruby, 63 61 53 38 bytes

Nova abordagem graças ao manatwork:

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

Velho:

->n{(1..n).reduce(:*).to_s.chars.map(&:hex).reduce:+}
  • -3 bytes graças a Martin Ender
  • -5 bytes graças a GB
TuxCrafting
fonte
1
O velho chato evalmaneira: ->n{eval"#{(1..n).reduce:*}".chars*?+}.
manatwork
6

Pitão, 7 6 bytes

Obrigado a @Kade por me salvar um byte

sj.!QT

Experimente online!

Esta é a minha primeira vez usando Pyth, por isso tenho certeza de que minha resposta pode ser um tanto quanto complicada.

Explicação:

s Sum
  j the digits of
    .! the factorial of
      Q the input
    T in base 10
BookOwl
fonte
1
10é atribuído a uma variável T, de modo que você pode fazer isso sj.!QT:)
Kade
OK, obrigado! Vou adicioná-lo
BookOwl 23/11
Agradável! ssM`.!faz o trabalho também, também em 6 bytes.
hakr14
5

Haskell, 41 40 bytes

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

Exemplo de uso: f 985-> 10053.

Faça uma lista de 1 para x, calcule o produto dos elementos da lista, transforme-o em sua representação de sequência, transforme cada caractere em um número e some-o.

Edit: @Angs salvou um byte. Obrigado!

nimi
fonte
f x=sum$read.pure<$>(show$product[1..x])salva um byte
Angs 23/11
5

Python, 54 bytes

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

repl.it

Jonathan Allan
fonte
Eu só veio com uma versão um pouco pior isso que parece maneira muito semelhante para que seja uma resposta em separado. Bravo
osuka_
5

R, 58 53 bytes

Edit: Salvo um byte graças a @Jonathan Carroll e alguns graças a @Micky T

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

Infelizmente, com números inteiros de 32 bits, isso funciona apenas para n < 22. Leva a entrada de stdin e as saídas para stdout.

Se alguém quiser uma precisão de nível mais alto, precisará usar alguma biblioteca externa, como Rmpfr:

sum(as.numeric(el(strsplit(paste(factorial(Rmpfr::mpfr(scan()))),""))))
Billywob
fonte
1
I chegou à mesma resposta exata como você fez, em seguida, encontrou um ganho de 1 byte em c(x,"")vs paste(x): sum(as.integer(el(strsplit(c(factorial(scan()),""),"")))). Coage o resultado fatorial ao caractere e o strsplitretorna como uma segunda lista, portanto, elainda funciona e extrai os primeiros elementos da lista.
22816 Jonathan Carroll
2
que tal prod(1:scan())?
MickyT
1
Também as.double deve ser suficiente
MickyT
@MickyT Thanks! Atualizada.
Billywob
strtoifunciona como uma substituição mais curta as.double, eu acho.
Giuseppe
4

Pip , 8 bytes

$+$*++,a

Experimente online!

Explicação

      ,a    # range
    ++      # increment
  $*        # fold multiplication
$+          # fold sum
Emigna
fonte
Desculpe, na verdade, consegui postar uma resposta 05AB1E antes de você;).
Magic Octopus Urn
2
@carusocomputing: Hehe. Me deu a oportunidade de procurar um novo idioma :)
Emigna
1
Acho que você é o primeiro, além de mim, a usar Pip como uma resposta não poliglota ao golfe. : D
DLosc
4

CJam , 8 bytes

rim!Ab:+

Experimente online!

Explicação

r   e# Read input.
i   e# Convert to integer.
m!  e# Take factorial.
Ab  e# Get decimal digits.
:+  e# Sum.
Martin Ender
fonte
3

Braquilog , 5 bytes

$!@e+

Experimente online!

Explicação

Basicamente, o 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
Fatalizar
fonte
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;
jacksonecac
fonte
@EyalLev Não há limite especificado na pergunta. Como você espera por muito tempo lidar com um fatorial que equivale a maior que 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}

Agradecimentos a Martin pela ajuda no golfe.

GB
fonte
3

Pushy , 4 bytes

fsS#

Dar entrada na linha de comando: $ pushy facsum.pshy 5. Aqui está o detalhamento:

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

Oitava, 30 bytes

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

Calcula o fatorial usando o produto da lista [1 2 ... n]. Converte-o em uma string e subtrai 48de todos os elementos (código ASCII para 0). Finalmente, resume-se :)

Stewie Griffin
fonte
3

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

Certamente não é o mais elegante, mas o desafio

seq -s\* $1|bc|fold -1|jq -s add
Adão
fonte
fold -1salva um byte.
Digital Trauma
@DigitalTrauma corrigido! graças
Adam
3

C, 58 bytes

Isto não é perfeito. Só funciona porque um tem que ser -1 no início. A idéia é usar duas funções recursivas em uma função. Não foi tão fácil como eu pensava.

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

Uso e formato compreensível:

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));
}

Edit: Encontrei o método que permite usar essa função várias vezes, mas o comprimento é 62 bytes.

a,b;k(i){a=b?a:i+(--b);return a?k(i*a--):i?i%10+k(i/10):++b;}
teksturi
fonte
Boa ideia, mas não entendo por que não seria mais curto usar uma função para retornar o fatorial e outra para calcular a soma dos dígitos, como a (b (10)). A palavra "retorno" é longa demais para que isso funcione?
JollyJoker #
O retorno come muito. Eu tento isso, é claro. Talvez alguém possa fazer isso pelo menos eu não consegui esse trabalho
teksturi
1
você pode aceitar dois argumentos para salvar alguns 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
}
Brad Gilbert b2gills
fonte
Parabéns, você conseguiu a resposta não. 101010!
RudolfJelin
@ RudolfL.Jelínek isso não é nada, em StackOverflow e Meta.StackExchange I número de usuário am 1337
Brad Gilbert b2gills
3

Cubix, 33 32 bytes

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

Formulário líquido:

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

Experimente online!

Notas

  • Funciona com entradas de até 170 entradas, inclusive superiores, resultando em um loop infinito, porque seu fatorial produz o Infinitynúmero (tecnicamente falando, é uma propriedade não gravável, não enumerável e não configurável do objeto de janela).
  • A precisão é perdida para as entradas 19 e superiores, porque números maiores que 2 53 (= 9 007 199 254 740 992) não podem ser armazenados com precisão em JavaScript.

Explicação

Este programa consiste em dois loops. O primeiro calcula o fatorial da entrada, o outro divide o resultado em seus dígitos e os soma. A soma é impressa e o programa termina.

Começar

Primeiro, precisamos preparar a pilha. Para essa parte, usamos as três primeiras instruções. O IP começa na quarta linha, apontando para o leste. A pilha está vazia.

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

Manteremos a soma no final da pilha, portanto, precisamos começar 0sendo a soma armazenando-a no final da pilha. Então precisamos pressionar um1 , porque a entrada será multiplicada inicialmente pelo número antes dela. Se fosse zero, o fatorial sempre produziria zero também. Por fim, lemos a entrada como um número inteiro.

Agora, a pilha está [0, 1, input]e o IP está na quarta linha, na quarta coluna, apontando para leste.

Laço fatorial

Este é um loop simples que multiplica os dois principais elementos da pilha (o resultado do loop anterior e da entrada - n, e depois diminui a entrada. Ele interrompe quando a entrada atinge 0. A $instrução faz com que o IP pule a u- O loop é a seguinte parte do cubo: O IP começa na quarta linha, quarta coluna.

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

Por causa do ^personagem, o IP começa a se mover para o norte imediatamente. Em seguida, ele ugira o IP e o move um para a direita. Na parte inferior, há outra seta: <aponta o IP de volta para o ^. A pilha começa como [previousresult, input-n], onde nestá o número de iterações. Os seguintes caracteres são executados no loop:

*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]

Em seguida, a parte superior da pilha (entrada reduzida) é comparada 0pela !instrução e, se estiver 0, au caractere é ignorado.

Soma os dígitos

O IP envolve o cubo, terminando no último caractere da quarta linha, inicialmente apontando para o oeste. O loop a seguir consiste em praticamente todos os caracteres restantes:

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

O loop primeiro exclui o item superior da pilha (que é um 10ou 0) e, em seguida, verifica o que resta do resultado do fatorial. Se isso foi reduzido para 0, a parte inferior da pilha (a soma) é impressa e o programa para. Caso contrário, as seguintes instruções serão executadas (a pilha começa 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]

E o loop começa novamente, até factorial/10igual a 0.

Luke
fonte
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));
}
user84207
fonte
2

Python, 57 bytes

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

Experimente online

mbomb007
fonte
Você poderia usar ticks de volta em vez de str?
nedla2004
2
@ nedla2004 Isso acrescentaria uma Lvez que o fatorial é grande o suficiente para se tornar um longo.
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%

Convenientemente set/afunciona com o valor atual de uma variável, portanto normalmente funciona dentro de um loop. Funciona apenas até 12 devido às limitações do tipo inteiro do Lote, portanto, em teoria, eu poderia salvar um byte assumindo 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%

Mas dessa maneira está a loucura ... Eu também poderia codificar a lista nesse 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
Neil
fonte
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

Funciona apenas n=22devido a limitações de precisão de ponto flutuante.

Neil
fonte
2

Befunge 93 , 56 54 bytes

Economizou 2 bytes no uso de get em vez de aspas. Isso permite que eu mude as 2 principais linhas sobre 1, reduzindo o espaço em branco desnecessário.

Experimente online!

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

Explicação:

&#:<                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.
MildlyMilquetoast
fonte
Você está certo. Estou trabalhando em uma nova versão. Para sua informação, estou usando o quickster.com, porque outros que eu encontrei não tratavam `` corretamente quando havia apenas um # na pilha.
MildlyMilquetoast
Obrigado! Parece que esse código só funciona corretamente na versão Befunge-98 , provavelmente por causa do método put.
MildlyMilquetoast
48 bytes , que também lida com 0 corretamente
Jo rei
2

Javascript ES6 - 61 54 bytes

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

EDIT: Obrigado Hedi e ETHproductions por reduzir 7 bytes. Vou ter que me lembrar desse truque t - = - j.

Marcus Dirr
fonte
1
Boa resposta! Você pode salvar alguns bytes de várias maneiras:n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
ETHproductions
@ETHproductions Mais alguns bytes podem ser salvos com eval:n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
Hedi
@Hedi Eu sei, eu estava dando um passo de cada vez :-)
ETHproductions
2

AHK , 60 bytes

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

O AutoHotkey não possui uma função fatorial interna e as funções de loop têm nomes longos para suas variáveis ​​internas. O primeiro loop é o fatorial e o segundo é somar os dígitos.

Engenheiro Toast
fonte
2

J, 12 11 bytes

Guardado 1 byte graças a cole!

1#.10#.inv!

Isso simplesmente aplica sum ( 1#.) aos dígitos (usando a invconversão inversa da base #.com uma base de 10) do fatorial ( !) do argumento.

Casos de teste

Nota: os dois últimos casos de teste são bigints, conforme marcado por um final x.

   f=:10#.inv!
   (,. f"0) 10 19 469x 985x
 10    27
 19    45
469  4140
985 10053
Conor O'Brien
fonte
Você pode usar "."0":para obter dígitos
Bolce Bussiere 4/18/18
11 bytes: o 1#.,.&.":@!que requer precisão estendida também para casos menores (não sei por que). Também 11 bytes: 1#.10#.inv!.
Cole
1

C, 63 bytes 60

-3 byte para do...whileloop.

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

Ungolfed e 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));
}
Karl Napf
fonte
Definimos f (n) como intpadrão?
Mukul Kumar 25/11
@MukulKumar isso é padrão em C, se não houver nenhum tipo, então inté assumido.
Karl Napf