Faktorielle Zahlensumme


25

Die Herausforderung besteht darin, die Ziffernsumme der Fakultät einer Zahl zu berechnen.


Beispiel

Input: 10
Output: 27

10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800 und die Summe der Ziffern in der Zahl 10! ist 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27

Sie können davon ausgehen, dass die Eingabe eine Ganzzahl über 0 ist. Die Ausgabe kann von einem beliebigen Typ sein, die Antwort sollte jedoch in der Standardbasis der Codierungssprache erfolgen.


Testfälle:

10    27
19    45
469   4140
985   10053

Hinweis: Einige Sprachen unterstützen keine großen Zahlen über 32-Bit-Ganzzahlen. Für diese Sprachen wird nicht erwartet, dass Sie große Fakultäten berechnen.

OEIS Link hier dank Martin Ender


Das ist , also gewinnt der kürzeste Code in Zeichen!


Was ist die maximal zu erwartende Eingangsanzahl? Mit 32-Bit-Ganzzahlen in R kann diese Herausforderung nicht mehr genau gelöst werdenn>21
Billywob,

1
@ Billywob Für R müssen Sie dann nur bis 20 gehen. Ich werde Frage bearbeiten, um dies zu reflektieren
George

Antworten:





7

C ++ 11, 58 Bytes

Als unbenanntes Lambda, das seine Eingabe ändert:

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

Einer der seltenen Fälle, in denen mein C ++ - Code kürzer als der C-Code ist .

Wenn Sie größere Fälle unterstützen möchten, wechseln Sie zu C ++ 14 und verwenden Sie:

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

und versorge das aufrufende Argument mit einem ullSuffix.

Verwendung:

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

Neuer Ansatz dank Handarbeit:

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

Alt:

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

1
Die alte langweilige evalArt und Weise: ->n{eval"#{(1..n).reduce:*}".chars*?+}.
Handarbeit

6

Pyth, 7 6 Bytes

Vielen Dank an @Kade, dass du mir ein Byte gespart hast

sj.!QT

Probieren Sie es online!

Ich benutze Pyth zum ersten Mal, daher bin ich mir sicher, dass meine Antwort ziemlich gut sein könnte.

Erläuterung:

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

1
10ist einer Variablen zugeordnet T, so dass Sie dies machen können sj.!QT:)
Kade

OK danke! Ich werde es hinzufügen
BookOwl

Nett! ssM`.!erledigt die Arbeit auch in 6 Bytes.
Hakr14

5

Haskell, 41-40 Bytes

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

Anwendungsbeispiel: f 985-> 10053.

Machen Sie eine Liste von 1bisx , berechnen Sie das Produkt der Listenelemente, wandeln Sie es in eine Zeichenfolgendarstellung um, wandeln Sie jedes Zeichen in eine Zahl um und addieren Sie sie.

Bearbeiten: @Angs hat ein Byte gespeichert. Vielen Dank!


f x=sum$read.pure<$>(show$product[1..x])speichert ein 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


Ich habe mir gerade eine etwas schlechtere Version ausgedacht, die viel zu ähnlich aussieht , als dass es eine separate Antwort wäre. Bravo
osuka_

5

R, 58 53 Bytes

Bearbeiten: Ein Byte dank @Jonathan Carroll und ein paar dank @Micky T gespeichert

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

Leider funktioniert dies mit 32-Bit-Ganzzahlen nur für n < 22. Übernimmt die Eingabe von stdin und die Ausgabe von stdout.

Wenn man eine höhere Präzision möchte, müsste man eine externe Bibliothek verwenden, wie zum Beispiel Rmpfr:

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

1
Ich habe genau die gleiche Antwort wie Sie erhalten und dann einen 1-Byte-Gewinn für c(x,"")vs paste(x): gefunden sum(as.integer(el(strsplit(c(factorial(scan()),""),"")))). Erzwingt die Umwandlung des Fakultätsergebnisses in ein Zeichen und strsplitgibt es als zweite Liste zurück. Funktioniert also elweiterhin und extrahiert die ersten Listenelemente.
Jonathan Carroll

2
wie wäre es prod(1:scan())?
MickyT

1
auch as.double ausreichen sollte
MickyT

@ MickyT Danke! Aktualisiert.
Billywob

strtoifunktioniert als kürzerer ersatz as.double, denke ich.
Giuseppe

4

Pip , 8 Bytes

$+$*++,a

Probieren Sie es online!

Erläuterung

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

Entschuldigung, es ist mir tatsächlich gelungen, eine 05AB1E-Antwort vor Ihnen zu posten;).
Magic Octopus Urn

2
@carusocomputing: Hehe.
Habe

1
Ich denke, Sie sind der erste neben mir, der Pip für eine nicht-mehrsprachige Code-Golf-Antwort verwendet. : D
DLosc


3

Brachylog , 5 Bytes

$!@e+

Probieren Sie es online!

Erläuterung

Grundsätzlich gilt der beschriebene Algorithmus:

$!       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 In der Frage ist kein Limit angegeben. Wie erwarten Sie, dass ein Faktor größer als 9.223.372.036.854.775.807 ist?
Jacksonecac

3

Ruby, 63 60 53 51 Bytes

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

Vielen Dank an Martin für die Golfhilfe.


3

Aufdringlich , 4 Bytes

fsS#

Geben Sie Eingabe auf der Kommandozeile: $ pushy facsum.pshy 5. Hier ist die Aufteilung:

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

3

Oktave, 30 Bytes

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

Berechnet die Fakultät aus dem Produkt der Liste [1 2 ... n]. Wandelt es in einen String um und subtrahiert 48von allen Elementen (ASCII-Code für 0). Endlich ist es soweit :)


3

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

Sicherlich nicht die eleganteste, aber für die Herausforderung

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

fold -1Speichert ein Byte.
Digitales Trauma

@DigitalTrauma korrigiert! Danke
Adam

3

C 58 Bytes

Das ist nicht perfekt. Funktioniert nur, da a beim Start -1 sein muss. Die Idee ist, zwei rekursive Funktionen in einer Funktion zu verwenden. Es war nicht so einfach, wie ich zuerst dachte.

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

Verwendung und verständliches Format:

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

Bearbeiten: Ich habe eine Metode gefunden, die diese Funktion mehrmals verwendet, aber dann ist die Länge 62 Bytes.

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

Gute Idee, aber ich verstehe nicht ganz, warum es nicht kürzer wäre, eine Funktion zum Zurückgeben der Fakultät und eine andere zum Berechnen der Ziffernsumme wie a (b (10)) zu verwenden. Ist das Wort "return" zu lang, um zu funktionieren?
JollyJoker

Rückkehr isst viel. Das versuche ich natürlich. Vielleicht kann es jemand tun, zumindest konnte ich diese Arbeit nicht bekommen
teksturi

1
Sie könnten zwei Argumente akzeptieren, um ein paar Bytes zu sparen: codegolf.stackexchange.com/a/153132/77415
user84207

3

Perl 6 , 21 Bytes

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

Erweitert:

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

Herzlichen Glückwunsch, Sie haben die Antwort Nein erhalten. 101010!
RudolfJelin

@ RudolfL.Jelínek Das ist nichts, auf Stackoverflow und Meta.StackExchange Ich bin Benutzernummer 1337
Brad Gilbert b2gills

3

Cubix, 33 32 Bytes

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

Netzform:

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

Probieren Sie es online!

Anmerkungen

  • Arbeitet mit Eingaben bis einschließlich 170, führen höhere Eingaben zu einer Endlosschleife, da ihre Fakultät die InfinityZahl ergibt (technisch gesehen eine nicht beschreibbare, nicht aufzählbare und nicht konfigurierbare Eigenschaft des Fensterobjekts).
  • Bei Eingaben ab 19 geht die Genauigkeit verloren, da Zahlen über 2 53 (= 9 007 199 254 740 992) in JavaScript nicht genau gespeichert werden können.

Erläuterung

Dieses Programm besteht aus zwei Schleifen. Der erste berechnet die Fakultät der Eingabe, der andere teilt das Ergebnis in seine Ziffern auf und addiert diese. Dann wird die Summe gedruckt und das Programm beendet.

Start

Zuerst müssen wir den Stapel vorbereiten. Für diesen Teil verwenden wir die ersten drei Anweisungen. Die IP beginnt in der vierten Zeile und zeigt nach Osten. Der Stapel ist leer.

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

Wir behalten die Summe ganz unten im Stapel, also müssen wir 0als Summe beginnen, indem wir diese auf der Unterseite des Stapels speichern. Dann müssen wir a drücken 1, da die Eingabe zunächst mit der Zahl davor multipliziert wird. Wenn dies Null wäre, würde die Fakultät immer auch Null ergeben. Zuletzt lesen wir die Eingabe als Ganzzahl.

Jetzt ist der Stapel [0, 1, input]und die IP ist in der vierten Zeile, der vierten Spalte, und zeigt nach Osten.

Fakultätsschleife

Dies ist eine einfache Schleife , dass multipliziert die obere beiden Elemente des Stapels (das Ergebnisses der vorherigen Schleife und der Eingangs - n, und dann dekrementiert den Eingang Es bricht , wenn der Eingang erreicht 0. Der. $Befehl die bewirkt , dass die IP -überspringen u- turn. Die Schleife ist der folgende Teil des Cubes: Die IP beginnt in der vierten Zeile, der vierten Spalte.

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

Aufgrund des ^Charakters bewegt sich die IP sofort nach Norden. Dann udreht der die IP um und verschiebt sie nach rechts. Unten befindet sich ein weiterer Pfeil: <Richtet die IP zurück in die ^. Der Stapel beginnt wie folgt [previousresult, input-n]: Wo nist die Anzahl der Iterationen? Die folgenden Zeichen werden in der Schleife ausgeführt:

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

Dann wird die Oberseite des Stapels (verringerte Eingabe) 0durch die !Anweisung überprüft , und wenn dies 0der uFall ist , wird das Zeichen übersprungen.

Summiere die Ziffern

Die IP-Adresse wird um den Würfel gewickelt und endet beim letzten Zeichen in der vierten Zeile, das anfänglich nach Westen zeigt. Die folgende Schleife besteht aus so ziemlich allen verbleibenden Zeichen:

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

Die Schleife löscht zuerst das oberste Element aus dem Stapel (entweder 10oder 0) und prüft dann, was vom Ergebnis der Fakultät übrig bleibt. Wenn dies auf verringert wurde, 0wird der Boden des Stapels (die Summe) gedruckt und das Programm angehalten. Andernfalls werden die folgenden Anweisungen ausgeführt (Stack startet als [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]

Und die Schleife beginnt erneut, bis factorial/100 ist.


3

C 47 Bytes

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

Verwendung:

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

Batch, 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%

Funktioniert praktisch set/amit dem aktuellen Wert einer Variablen, funktioniert also normalerweise innerhalb einer Schleife. Funktioniert aufgrund der Beschränkungen des Batch-Integer-Typs nur bis zu 12, daher könnte ich theoretisch ein Byte sparen, indem ich annehme 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%

Aber so liegt der Wahnsinn ... Ich könnte die Liste in diesem Fall genauso gut hart codieren (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 Byte

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

Funktioniert nur n=22aufgrund von Einschränkungen der Gleitkommagenauigkeit.


2

Befunge 93 , 56 54 Bytes

2 Bytes gespart, um get anstelle von Anführungszeichen zu verwenden. Auf diese Weise kann ich die obersten 2 Zeilen über 1 verschieben und unnötigen Leerraum reduzieren.

Probieren Sie es online!

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

Erläuterung:

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

Du hast Recht. Ich arbeite an einer neuen Version. Zu Ihrer Information, ich benutze quickster.com, weil andere, die ich gefunden habe, `` nicht richtig behandelt haben, als es nur ein # im Stapel gab.
MildlyMilquetoast

Vielen Dank! Es sieht so aus, als ob dieser Code nur in der Befunge-98- Version ordnungsgemäß funktioniert , wahrscheinlich aufgrund der put-Methode.
MildlyMilquetoast

48 Bytes, die auch 0 richtig behandelt
Jo King

2

Javascript ES6 - 61 54 Bytes

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

BEARBEITEN: Danke an Hedi und ETHproductions für das Abschneiden von 7 Bytes. Ich muss mich an diesen Trick erinnern.


1
Gute Antwort! Sie können ein paar Bytes auf verschiedene Arten n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
speichern

@ETHproductions Einige weitere Bytes können mit eval gespeichert werden:n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
Hedi

@Hedi Ich weiß, ich habe es Schritt für Schritt gemacht :-)
ETHproductions

2

AHK , 60 Bytes

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

AutoHotkey hat keine eingebaute Fakultätsfunktion und die Schleifenfunktionen haben lange Namen für ihre eingebauten Variablen. Die erste Schleife ist die Fakultät und die zweite addiert die Ziffern.


2

J, 12 11 Bytes

Dank cole 1 Byte gespart!

1#.10#.inv!

Dies wendet einfach sum ( 1#.) auf die Ziffern (unter Verwendung der Umkehrung invder Basisumwandlung #.mit einer Basis von 10) der Fakultät an (! ) des Arguments an.

Testfälle

Hinweis: Die letzten beiden Testfälle sind Bigints, die durch ein Trailing gekennzeichnet sind x.

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

Sie können verwenden "."0":, um Ziffern zu erhalten
Bolce Bussiere

11 Bytes: 1#.,.&.":@!Dies erfordert eine erweiterte Genauigkeit auch für kleinere Fälle (unsicher, warum). Auch 11 Bytes 1#.10#.inv!.
Cole


1

C 63 60 Bytes

-3 Byte für do...whileSchleife.

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

Ungolfed und Nutzung:

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

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

Definieren wir f (n) als intStandard?
Mukul Kumar

@MukulKumar Dies ist Standard in C, wenn es keinen Typ intgibt, wird angenommen.
Karl Napf
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.