Somme des chiffres factoriels


25

Le défi consiste à calculer la somme des chiffres de la factorielle d'un nombre.


Exemple

Input: 10
Output: 27

dix! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, et la somme des chiffres du nombre 10! est 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27

Vous pouvez vous attendre à ce que l'entrée soit un entier supérieur à 0. La sortie peut être de n'importe quel type, mais la réponse doit être dans la base standard du langage de codage.


Cas de test:

10    27
19    45
469   4140
985   10053

NB Certaines langues ne prennent pas en charge les grands nombres supérieurs à des entiers 32 bits; pour ces langues, vous ne devrez pas calculer de grandes factorielles.

Lien OEIS ici grâce à Martin Ender


C'est le , donc le code le plus court en caractères gagne!


Quel est le nombre maximum d'entrées à prévoir? Avec des entiers 32 bits dans R, ce défi ne peut pas être résolu avec précision aprèsn>21
Billywob

1
@Billywob Pour R, vous n'aurez qu'à aller à 20. Je modifierai la question pour refléter cela
George

Réponses:





7

C ++ 11, 58 octets

Comme lambda sans nom modifiant son entrée:

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

L' un des rares cas où mon code C ++ est plus court que le code C .

Si vous souhaitez prendre en charge des cas plus volumineux, passez en C ++ 14 et utilisez:

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

et fournissez l'argument appelant avec le ullsuffixe.

Usage:

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

Rubis, 63 61 53 38 octets

Nouvelle approche grâce au manatwork:

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

Vieux:

->n{(1..n).reduce(:*).to_s.chars.map(&:hex).reduce:+}
  • -3 octets grâce à Martin Ender
  • -5 octets grâce à GB

1
Le vieux ennuyeux evalchemin: ->n{eval"#{(1..n).reduce:*}".chars*?+}.
manatwork

6

Pyth, 7 6 octets

Merci à @Kade de m'avoir sauvé un octet

sj.!QT

Essayez-le en ligne!

C'est la première fois que j'utilise Pyth, donc je suis sûr que ma réponse pourrait être assez jouée.

Explication:

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

1
10est assigné à une variable T, vous pouvez donc le faire sj.!QT:)
Kade

OK merci! Je vais l'ajouter
BookOwl

Agréable! ssM`.!fait le travail aussi, également en 6 octets.
hakr14

5

Haskell, 41 40 octets

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

Exemple d'utilisation: f 985-> 10053.

Faites une liste de 1à x, calculez le produit des éléments de la liste, transformez-le en sa représentation sous forme de chaîne, transformez chaque caractère en nombre et additionnez-les.

Modifier: @Angs a enregistré un octet. Merci!


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

5

Python, 54 octets

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

repl.it


Je viens juste de proposer une version légèrement pire de cela qui semble beaucoup trop similaire pour que ce soit une réponse distincte. Bravo
osuka_

5

R, 58 53 octets

Edit: Enregistré un octet grâce à @Jonathan Carroll et un couple grâce à @Micky T

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

Malheureusement, avec des entiers 32 bits, cela ne fonctionne que pour n < 22. Prend les entrées de stdin et les sorties vers stdout.

Si l'on souhaite une précision de niveau supérieure, il faudrait utiliser une bibliothèque externe telle que Rmpfr:

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

1
Je suis arrivé exactement la même réponse que vous avez fait, puis trouvé un gain de 1 octet sur c(x,"")vs paste(x): sum(as.integer(el(strsplit(c(factorial(scan()),""),"")))). Force le résultat factoriel au caractère et le strsplitrenvoie comme une deuxième liste, donc elfonctionne toujours et extrait les premiers éléments de la liste.
Jonathan Carroll

2
que diriez-vous prod(1:scan())?
MickyT

1
as.double devrait également suffire
MickyT

@MickyT Merci! Mis à jour.
Billywob

strtoifonctionne comme un remplacement plus court as.double, je pense.
Giuseppe

4

Pip , 8 octets

$+$*++,a

Essayez-le en ligne!

Explication

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

Désolé, j'ai réussi à poster une réponse 05AB1E devant vous;).
Urne de poulpe magique

2
@carusocomputing: Hehe. J'ai eu l'occasion de me pencher sur une nouvelle langue :)
Emigna

1
Je pense que vous êtes le premier à côté de moi à utiliser Pip pour une réponse de golf à code non polyglotte. : D
DLosc


3

Brachylog , 5 octets

$!@e+

Essayez-le en ligne!

Explication

Fondamentalement, l'algorithme décrit:

$!       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 octets

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 Aucune limite n'est spécifiée dans la question. Comment attendez-vous longtemps pour gérer une factorielle équivalant à plus de 9 223 372 036 854 775 807?
jacksonecac

3

Rubis, 63 60 53 51 octets

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

Merci à Martin pour son aide au golf.


3

Pushy , 4 octets

fsS#

Donnez entrée sur la ligne de commande: $ pushy facsum.pshy 5. Voici la ventilation:

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

3

Octave, 30 octets

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

Calcule la factorielle en prenant le produit de la liste [1 2 ... n]. Le convertit en chaîne et soustrait 48de tous les éléments (code ASCII pour 0). Enfin ça résume :)


3

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

Sûrement pas le plus élégant mais pour le défi

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

fold -1enregistre un octet.
Digital Trauma

@DigitalTrauma corrigé! merci
Adam

3

C, 58 octets

Ce n'est pas parfait. Fonctionne uniquement car un doit être -1 au début. L'idée est d'utiliser deux fonctions récursives dans une seule fonction. Ce n'était pas aussi facile que je le pensais.

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

Utilisation et format compréhensible:

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: j'ai trouvé un métode qui permettait d'utiliser cette fonction plusieurs fois mais la longueur était de 62 octets.

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

Bonne idée, mais je ne comprends pas très bien pourquoi il ne serait pas plus court d'utiliser une fonction pour renvoyer la factorielle et une autre pour calculer la somme des chiffres, comme un (b (10)). Le mot «retour» est-il trop long pour que cela fonctionne?
JollyJoker

Le retour mange beaucoup. J'essaye bien sûr. Peut-être que quelqu'un peut le faire au moins je n'ai pas pu obtenir ce travail
teksturi

1
vous pouvez accepter deux arguments pour économiser quelques octets: codegolf.stackexchange.com/a/153132/77415
user84207

3

Perl 6 , 21 octets

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

Étendu:

{  # 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
}

Félicitations, vous avez obtenu la réponse non. 101010!
RudolfJelin

@ RudolfL.Jelínek Ce n'est rien, sur StackOverflow et Meta.StackExchange Je suis le numéro d'utilisateur 1337
Brad Gilbert b2gills

3

Cubix, 33 32 octets

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

Forme nette:

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

Essayez-le en ligne!

Remarques

  • Fonctionne avec des entrées jusqu'à 170 inclus, les entrées plus élevées entraînent une boucle infinie, car leur factorielle donne le Infinitynombre (techniquement parlant, c'est une propriété non inscriptible, non énumérable et non configurable de l'objet fenêtre).
  • La précision est perdue pour les entrées 19 et supérieures, car les nombres supérieurs à 2 53 (= 9 007 199 254 740 992) ne peuvent pas être stockés avec précision dans JavaScript.

Explication

Ce programme se compose de deux boucles. Le premier calcule la factorielle de l'entrée, l'autre divise le résultat en ses chiffres et les additionne. Ensuite, la somme est imprimée et le programme se termine.

Début

Tout d'abord, nous devons préparer la pile. Pour cette partie, nous utilisons les trois premières instructions. L'IP commence sur la quatrième ligne, pointant vers l'est. La pile est vide.

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

Nous conserverons la somme tout en bas de la pile, nous devons donc commencer par 0être la somme en la stockant au bas de la pile. Ensuite, nous devons appuyer sur a 1, car l'entrée sera initialement multipliée par le nombre précédent. Si c'était zéro, la factorielle donnerait toujours aussi zéro. Enfin, nous lisons l'entrée comme un entier.

Maintenant, la pile est [0, 1, input]et l'IP est à la quatrième ligne, la quatrième colonne, pointant vers l'est.

Boucle factorielle

Il s'agit d'une simple boucle qui multiplie les deux premiers éléments de la pile (le résultat de la boucle précédente et de l'entrée - n, puis décrémente l'entrée. Elle se rompt lorsque l'entrée atteint 0. L' $instruction fait que l'IP saute le u- La boucle est la partie suivante du cube. L'IP commence à la quatrième ligne, quatrième colonne.

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

En raison du ^caractère, l'IP commence immédiatement à se déplacer vers le nord. Ensuite, le utourne autour de l'IP et le déplace vers la droite. En bas, il y a une autre flèche: <pointe l'IP dans le ^. La pile commence comme [previousresult, input-n], où nest le nombre d'itérations. Les caractères suivants sont exécutés dans la boucle:

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

Ensuite, le haut de la pile (entrée diminuée) est vérifié 0par l' !instruction, et si c'est le cas 0, leu caractère est ignoré.

Additionnez les chiffres

L'IP s'enroule autour du cube, se terminant sur le tout dernier caractère de la quatrième ligne, pointant initialement vers l'ouest. La boucle suivante comprend à peu près tous les caractères restants:

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

La boucle supprime d'abord l'élément supérieur de la pile (qui est soit 10ou 0), puis vérifie ce qui reste du résultat de la factorielle. Si cela a été réduit à 0, le bas de la pile (la somme) est imprimé et le programme s'arrête. Sinon, les instructions suivantes sont exécutées (la pile commence comme [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]

Et la boucle recommence, jusqu'à ce qu'elle factorial/10soit égale à 0.


3

C, 47 octets

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

usage:

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 octets

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

Essayez-le en ligne


Pourriez-vous utiliser des ticks arrière au lieu de str?
nedla2004

2
@ nedla2004 Cela ajouterait une Lfois que la factorielle est assez grande pour devenir longue.
Kade

2

Lot, 112 octets

@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%

Fonctionne de manière pratique set/asur la valeur actuelle d'une variable, elle fonctionne donc normalement dans une boucle. Fonctionne uniquement jusqu'à 12 en raison des limitations du type entier de Batch, donc en théorie, je pourrais économiser un octet en supposant 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%

Mais de cette façon réside la folie ... Je pourrais aussi bien coder en dur la liste dans ce cas (97 octets):

@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 octets

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

Fonctionne uniquement en n=22raison de limitations de précision en virgule flottante.


2

Befunge 93 , 56 54 octets

2 octets enregistrés permettent d'utiliser get au lieu de guillemets. Cela m'a permis de décaler les 2 premières lignes sur 1, réduisant ainsi les espaces blancs inutiles.

Essayez-le en ligne!

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

Explication:

&#:<                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.

Vous avez raison. Je travaille sur une nouvelle version. Pour info, j'utilise quickster.com, car d'autres que j'ai trouvé n'ont pas traité `` correctement alors qu'il n'y avait qu'un seul # dans la pile.
MildlyMilquetoast

Merci! Il semble que ce code ne fonctionne correctement que dans la version Befunge-98 , probablement à cause de la méthode put.
MildlyMilquetoast

48 octets qui gèrent également 0 correctement
Jo King

2

Javascript ES6 - 61 54 octets

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

EDIT: Merci Hedi et ETHproductions pour avoir rasé 7 octets. Je dois me souvenir de cette astuce t - = - j.


1
Bonne réponse! Vous pouvez enregistrer quelques octets de différentes manières:n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
ETHproductions

@ETHproductions Quelques octets supplémentaires peuvent être enregistrés avec eval:n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
Hedi

@Hedi Je sais, je faisais un pas à la fois :-)
ETHproductions

2

AHK , 60 octets

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

AutoHotkey n'a pas de fonction factorielle intégrée et les fonctions de boucle ont des noms longs pour leurs variables intégrées. La première boucle est la factorielle et la seconde additionne les chiffres ensemble.


2

J, 12 11 octets

1 octet enregistré grâce à Cole!

1#.10#.inv!

Cela applique simplement sum ( 1#.) aux chiffres (en utilisant l'inverse invde la conversion de base #.avec une base de 10) de la factorielle ( !) de l'argument.

Cas de test

Remarque: les deux derniers cas de test sont des bigints, comme indiqué par une fin x.

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

Vous pouvez utiliser "."0":pour obtenir des chiffres
Bolce Bussiere

11 octets: 1#.,.&.":@!qui nécessite également une précision étendue pour les cas plus petits (vous ne savez pas pourquoi). En outre 11 octets: 1#.10#.inv!.
cole


1

C, 63 60 octets

-3 octets pour la do...whileboucle.

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

Non golfé et utilisation:

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

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

Définissons-nous f (n) intpar défaut?
Mukul Kumar

@MukulKumar c'est standard en C, s'il n'y a pas de type alors inton suppose.
Karl Napf
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.