Somma delle cifre fattoriali


25

La sfida è calcolare la somma delle cifre del fattoriale di un numero.


Esempio

Input: 10
Output: 27

10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800 e la somma delle cifre nel numero 10! è 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27

Puoi aspettarti che l'input sia un numero intero superiore a 0. L'output può essere di qualsiasi tipo, ma la risposta dovrebbe essere nella base standard del linguaggio di codifica.


Casi test:

10    27
19    45
469   4140
985   10053

NB Alcune lingue non possono supportare numeri grandi sopra numeri interi a 32 bit; per quelle lingue non ci si aspetta che calcoli fattoriali di grandi dimensioni.

Link OEIS qui grazie a Martin Ender


Questo è , quindi vince il codice più breve in caratteri!


Qual è il numero massimo di input da aspettarsi? Con numeri interi a 32 bit in R questa sfida non può essere risolta con precisionen>21
Billywob,

1
@Billywob Per R, allora dovrai solo andare a 20. Modificherò la domanda per riflettere questo
george

Risposte:





7

C ++ 11, 58 byte

Come lambda senza nome che modifica il suo input:

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

Uno dei rari casi in cui il mio codice C ++ è più breve del codice C .

Se si desidera supportare casi più grandi, passare a C ++ 14 e utilizzare:

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

e fornire l'argomento chiamante con il ullsuffisso.

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 byte

Nuovo approccio grazie all'opera d'arte:

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

Vecchio:

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

1
Il vecchio noioso evalmodo: ->n{eval"#{(1..n).reduce:*}".chars*?+}.
arte

6

Pyth, 7 6 byte

Grazie a @Kade per avermi salvato un byte

sj.!QT

Provalo online!

Questa è la prima volta che utilizzo Pyth, quindi sono sicuro che la mia risposta potrebbe essere giocata un po 'a golf.

Spiegazione:

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

1
10è assegnato a una variabile T, quindi puoi farlo sj.!QT:)
Kade,

Ok grazie! Lo aggiungerò
BookOwl il

Bello! ssM`.!fa anche il lavoro, anche in 6 byte.
hakr14,

5

Haskell, 41 40 byte

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

Esempio di utilizzo: f 985-> 10053.

Crea un elenco da 1a x, calcola il prodotto degli elementi dell'elenco, trasformalo nella sua rappresentazione di stringa, trasforma ogni carattere in un numero e sommali.

Modifica: @Angs ha salvato un byte. Grazie!


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

5

Python, 54 byte

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

repl.it


Sono venuto con una versione leggermente peggiore di questo che sembra così troppo simili per essere una risposta separata. Bravo
osuka_

5

R, 58 53 byte

Modifica: salvato un byte grazie a @Jonathan Carroll e un paio grazie a @Micky T

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

Sfortunatamente, con numeri interi a 32 bit, funziona solo per n < 22. Porta input da stdin e output a stdout.

Se si desidera una precisione di livello superiore, è necessario utilizzare una libreria esterna come Rmpfr:

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

1
Ho raggiunto la stessa risposta esatta, come avete fatto, quindi trovato un guadagno di 1 byte su c(x,"")vs paste(x): sum(as.integer(el(strsplit(c(factorial(scan()),""),"")))). Costringe il risultato fattoriale a carattere e lo strsplitrestituisce come secondo elenco, quindi elfunziona ed estrae ancora i primi elementi dell'elenco.
Jonathan Carroll,

2
che ne dici prod(1:scan())?
MickyT,

1
anche as.double dovrebbe bastare
MickyT

@MickyT Grazie! Aggiornato.
Billywob,

strtoifunziona come un sostituto più breve as.double, credo.
Giuseppe,

4

Pip , 8 byte

$+$*++,a

Provalo online!

Spiegazione

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

Siamo spiacenti, in realtà sono riuscito a pubblicare una risposta 05AB1E prima di te;).
Magic Octopus Urn,

2
@carusocomputing: Hehe. Mi ha dato l'opportunità di esaminare una nuova lingua :)
Emigna,

1
Penso che tu sia il primo oltre a me ad usare Pip per una risposta golf non poliglotta. : D
DLosc,


3

Brachylog , 5 byte

$!@e+

Provalo online!

Spiegazione

Fondamentalmente l'algoritmo descritto:

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

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 Non ci sono limiti specificati nella domanda. Come ti aspetti a lungo da gestire un fattoriale che equivale a più di 9.223.372.036.854.775.807?
jacksonecac,

3

Rubino, 63 60 53 51 byte

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

Grazie a Martin per l'aiuto nel golf.


3

Pushy , 4 byte

fsS#

Dare un contributo sulla riga di comando: $ pushy facsum.pshy 5. Ecco la ripartizione:

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

3

Ottava, 30 byte

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

Calcola il fattoriale prendendo il prodotto dell'elenco [1 2 ... n]. Lo converte in una stringa e sottrae 48da tutti gli elementi (codice ASCII per 0). Alla fine lo riassume :)


3

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

Sicuramente non il più elegante ma per la sfida

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

fold -1salva un byte.
Trauma digitale,

@DigitalTrauma corretto! grazie
Adam,

3

C, 58 byte

Questo non è perfetto Funziona solo perché deve essere -1 all'inizio. L'idea è di utilizzare due funzioni ricorsive in una funzione. Non è stato facile come pensavo.

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

Formato d'uso e comprensibile:

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

Modifica: ho trovato metode che consente di utilizzare questa funzione più volte, ma la lunghezza è di 62 byte.

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

Bella idea, ma non capisco bene perché non sarebbe più breve usare una funzione per restituire il fattoriale e un'altra per calcolare la somma delle cifre, come a (b (10)). La parola "ritorno" è troppo lunga perché funzioni?
JollyJoker,

Il ritorno mangia molto. Lo provo ovviamente. Forse qualcuno può farcela almeno non riuscivo a ottenere quel lavoro
teksturi il

1
potresti accettare due argomenti per salvare alcuni byte: codegolf.stackexchange.com/a/153132/77415
user84207

3

Perl 6 , 21 byte

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

Allargato:

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

Complimenti, hai la risposta no. 101010!
RudolfJelin,

@ RudolfL.Jelínek Non è niente, su StackOverflow e Meta.StackExchange Sono il numero utente 1337
Brad Gilbert b2gills,

3

Cubix, 33 32 byte

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

Modulo netto:

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

Provalo online!

Gli appunti

  • Funziona con input fino a 170 inclusi, input più alti producono un loop infinito, perché il loro fattoriale produce il Infinity numero (tecnicamente parlando, è una proprietà non scrivibile, non enumerabile e non configurabile dell'oggetto finestra).
  • La precisione viene persa per gli input da 19 in poi, poiché i numeri superiori a 2 53 (= 9 007 199 254 740 992) non possono essere memorizzati con precisione in JavaScript.

Spiegazione

Questo programma è composto da due loop. Il primo calcola il fattoriale dell'input, l'altro divide il risultato nelle sue cifre e somma quelle insieme. Quindi viene stampata la somma e il programma termina.

Inizio

Innanzitutto, dobbiamo preparare la pila. Per quella parte, usiamo le prime tre istruzioni. L'IP inizia sulla quarta riga, puntando verso est. Lo stack è vuoto.

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

Manterremo la somma in fondo allo stack, quindi dobbiamo iniziare con l' 0essere la somma memorizzandola sul fondo dello stack. Quindi dobbiamo premere a1 , perché l'input verrà inizialmente moltiplicato per il numero prima di esso. Se questo fosse zero, anche il fattoriale produrrebbe sempre zero. Infine leggiamo l'input come un numero intero.

Ora, lo stack è [0, 1, input]e l'IP è alla quarta riga, la quarta colonna, che punta verso est.

Ciclo fattoriale

Questo è un semplice ciclo che moltiplica i primi due elementi dello stack (il risultato del ciclo precedente e l'input - n, quindi decrementa l'input. Si interrompe quando l'ingresso raggiunge 0. L' $istruzione fa sì che l'IP salti il u- Il ciclo è la parte seguente del cubo L'IP inizia sulla quarta riga, quarta colonna.

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

A causa del ^personaggio, l'IP inizia immediatamente a spostarsi a nord. Quindi ugira l'IP e lo sposta di uno a destra. In fondo, c'è un'altra freccia: <punta l'IP nuovamente in ^. Lo stack inizia come [previousresult, input-n], dov'è nil numero di iterazioni. I seguenti caratteri vengono eseguiti nel 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]

Quindi la parte superiore della pila (diminuzione ingresso) viene confrontato 0dal !istruzione, e se è 0il ucarattere è saltato.

Somma le cifre

L'IP si avvolge attorno al cubo, finendo sull'ultimo carattere sulla quarta riga, inizialmente rivolto verso ovest. Il ciclo seguente è composto praticamente da tutti i caratteri rimanenti:

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

Il ciclo elimina prima l'elemento in cima alla pila (che è o 10o 0), quindi controlla ciò che resta del risultato del fattoriale. Se è stato ridotto a 0, viene stampato il fondo della pila (la somma) e il programma si arresta. Altrimenti, vengono eseguite le seguenti istruzioni (lo stack inizia come [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 il ciclo ricomincia, fino a quando non è factorial/10uguale a 0.


3

C, 47 byte

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

utilizzo:

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 byte

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

Provalo online


Potresti usare le zecche posteriori invece di str?
nedla2004,

2
@ nedla2004 Questo aggiungerebbe una Lvolta che il fattoriale è abbastanza grande da diventare un lungo.
Kade,

2

Lotto, 112 byte

@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/aFunziona comodamente sul valore corrente di una variabile, quindi funziona normalmente all'interno di un ciclo. Funziona solo fino a 12 a causa delle limitazioni del tipo intero di Batch, quindi in teoria potrei salvare un byte assumendof<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%

Ma in questo modo risiede la follia ... Potrei anche codificare la lista in quel caso (97 byte):

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

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

Funziona solo fino a n=22limiti di precisione in virgola mobile.


2

Befunge 93 , 56 54 byte

I 2 byte salvati fanno usando get anziché le virgolette. Questo mi permette di spostare le prime 2 linee su 1, riducendo gli spazi bianchi non necessari.

Provalo online!

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

Spiegazione:

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

Hai ragione. Sto lavorando a una nuova versione. Cordiali saluti, sto usando quickster.com, perché gli altri che ho trovato non trattavano `` correttamente quando c'era solo un # nello stack.
MildlyMilquetoast,

Grazie! Sembra che questo codice funzioni correttamente solo nella versione Befunge-98 , probabilmente a causa del metodo put.
MildlyMilquetoast,

48 byte che gestisce anche 0 correttamente
Jo King

2

Javascript ES6 - 61 54 byte

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

EDIT: grazie Hedi ed ETHproductions per la rasatura di 7 byte. Dovrò ricordare quel trucco t - = - j.


1
Bella risposta! È possibile salvare un paio di byte in vari modi:n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
ETHproductions

@ETHproductions Alcuni altri byte possono essere salvati con eval:n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
Hedi

@Hedi lo so, stavo facendo un passo alla volta :-)
ETHproductions

2

AHK , 60 byte

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

AutoHotkey non ha una funzione fattoriale incorporata e le funzioni del ciclo hanno nomi lunghi per le loro variabili incorporate. Il primo ciclo è il fattoriale e il secondo sta sommando le cifre.


2

J, 12 11 byte

Salvato 1 byte grazie a Cole!

1#.10#.inv!

Questo semplicemente applica sum ( 1#.) alle cifre (usando l'inverso invdella conversione di base#. con una base di 10) del factorial ( !) dell'argomento.

Casi test

Nota: gli ultimi due casi di test sono nativi, come indicato da un finale x.

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

Puoi usare "."0":per ottenere cifre
Bolce Bussiere

11 byte: 1#.,.&.":@!ciò richiede una precisione estesa anche per i casi più piccoli (non so perché). Anche 11 byte: 1#.10#.inv!.
Cole


1

C, 63 60 byte

-3 byte per do...whileloop.

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

Ungolfed e utilizzo:

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

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

Definiamo f (n) come intimpostazione predefinita?
Mukul Kumar,

@MukulKumar questo è standard in C, se non c'è un tipo, allora intsi presume.
Karl Napf,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.