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!


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:





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

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

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

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!


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


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()))),""))))

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

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


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

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


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

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 :)


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

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

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
}

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.


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

Experimente online


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

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.


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.

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.


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.


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

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.