Faktörlü basamak toplamı


25

Buradaki zorluk, bir sayının faktörünün basamak toplamını hesaplamaktır.


Örnek

Input: 10
Output: 27

10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800 ve 10 rakamındaki rakamların toplamı! 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27'dir

Girişin 0'ın üzerinde bir tam sayı olmasını bekleyebilirsiniz. Çıktı her türden olabilir, ancak cevap kodlama dilinin standart tabanında olmalıdır.


Test durumları:

10    27
19    45
469   4140
985   10053

Not Bazı diller 32 bit tam sayıların üzerinde çok sayıda sayıyı destekleyemez; bu diller için büyük faktörleri hesaplamanız beklenmeyecektir.

Martin Ender sayesinde OEIS bağlantısı burada


Bu , karakterdeki en kısa kod kazanıyor!


Beklenecek maksimum giriş numarası nedir? R 32 bit tamsayı ile bu sorun doğru geçmiş çözülemezn>21
Billywob

1
@Billywob R için o zaman sadece 20'ye gitmen gerekecek. Bunu yansıtmak için soruyu düzenleyeceğim
george

Yanıtlar:





7

C ++ 11, 58 bayt

Adsız lambda girişini değiştirirken:

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

Nadir durumlarda biri benim C ++ kod daha kısa olduğunda C kodu .

Daha büyük vakalara destek vermek istiyorsanız, C ++ 14'e geçin ve kullanın:

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

ve çağıran argümanı ullsonek ile sağlayın.

Kullanımı:

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 bayt

İnsan yapımı sayesinde yeni yaklaşım:

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

Eski:

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

1
Eski sıkıcı evalyol: ->n{eval"#{(1..n).reduce:*}".chars*?+}.
Manat çalışması

6

Pyth, 7 6 bayt

Beni bir baytı kurtardığı için @Kade'e teşekkürler

sj.!QT

Çevrimiçi deneyin!

Bu Pyth'i ilk kez kullanıyorum, bu yüzden cevabımın birazcık golf olabileceğinden eminim.

Açıklama:

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

1
10bir değişkene atanır T, bu yüzden bunu yapabilirsiniz sj.!QT:)
Kade

Tamam teşekkürler! Ekleyeceğim
BookOwl

Güzel! ssM`.!işi de yapar, ayrıca 6 byte.
hakr14

5

Haskell, 41 40 bayt

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

Kullanım örneği: f 985-> 10053.

Bir liste yap 1üzere x, liste elemanlarının ürünü hesaplamak, dize gösterimine çevirmek, bir dizi halinde her bir karakteri açmak ve onları toplamak.

Düzenleme: @Angs bir bayt kaydetti. Teşekkürler!


f x=sum$read.pure<$>(show$product[1..x])bir bayt kazandırır
Angs

5

Python, 54 bayt

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

repl.it


Sadece görünüyor bu biraz daha kötü bir sürümü ile geldi yolu ayrı cevap için çok benzer. Bravo
osuka_

5

R, 58 53 bayt

Düzenleme: @Jonathan Carroll ve @Micky T sayesinde bir çift bir byte kurtarıldı

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

Ne yazık ki, 32-bit tamsayılarla, bu sadece işe yarar n < 22. Stdin'den girdi alır ve stdout'a çıktılar.

Biri daha yüksek düzeyde hassasiyet isterse, aşağıdaki gibi bazı harici kütüphaneleri kullanmak zorunda kalır Rmpfr:

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

1
Sizinle aynı cevaba ulaştım, sonra c(x,"")vs paste(x): 1-byte kazanç buldum sum(as.integer(el(strsplit(c(factorial(scan()),""),"")))). Faktöriyel sonucu karaktere zorlar ve strsplitikinci bir liste olarak döndürür, bu nedenle elhala çalışır ve ilk liste öğelerini çıkarır.
Jonathan Carroll,

2
nasıl prod(1:scan())?
MickyT

1
Ayrıca as.double yeterli
MickyT 24/16

@MickyT Teşekkürler! Güncellenmiş.
Billywob

strtoias.doublebence daha kısa bir yedek olarak çalışıyor .
Giuseppe

4

Pip , 8 bayt

$+$*++,a

Çevrimiçi deneyin!

açıklama

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

Üzgünüm, aslında sizden önce bir 05AB1E cevap göndermeyi başardım;).
Magic Octopus Urn

2
@carusocomputing: Hehe. Bana yeni bir dile bakma fırsatını yakaladım :)
Emigna 23:16

1
Bence Pip'i polglot olmayan bir kod golf yanıtı için kullanan benden başka sen de sensin. : D
DLosc


3

Brachylog , 5 bayt

$!@e+

Çevrimiçi deneyin!

açıklama

Temel olarak açıklanan algoritma:

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

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 Soruda belirtilen bir sınır yok. 9,223,372,036,854,775,807'den daha büyük bir faktörü ele almak için ne kadar beklemektesiniz?
jacksonecac

3

Ruby, 63 60 53 51 bayt

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

Golf yardımı için Martin'e teşekkür ederiz.


3

Pushy , 4 bayt

fsS#

Komut satırında girişi verin: $ pushy facsum.pshy 5. İşte dağılım:

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

3

Oktav, 30 bayt

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

Listenin ürününü alarak faktorial değerini hesaplar [1 2 ... n]. Bir dizgeye dönüştürür ve 48tüm elemanlardan çıkarır (ASCII kodu için 0). Sonunda özetliyor :)


3

bash (seq, bc, katla, jq), 34 33 bayt

Kesinlikle en zarif değil, meydan okuma için

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

fold -1bir bayt kaydeder.
Dijital Travma

@ DigitalTrauma düzeltildi! teşekkürler
Adam

3

C, 58 bayt

Bu mükemmel değil. Sadece olanlar çalışır çünkü başlangıçta -1 olması gerekir. Fikir, iki özyinelemeli işlevi bir işlevde kullanmaktır. İlk düşündüğüm kadar kolay değildi.

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

Kullanım ve anlaşılabilir 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));
}

Düzenleme: Bu işlevi çok kez kullanmasına izin veren metodu buldum ancak uzunluğu 62 bayttır.

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

Güzel bir fikir, ancak faktörü döndürmek için bir işlevi, diğeri toplamını hesaplamak için neden bir işlevi kullanmanın daha kısa olmadığını anlamıyorum, (b (10)). Bunun için "dönüş" kelimesi çok mu uzun?
JollyJoker,

Geri dönüş çok yiyor. Bunu elbette deniyorum. Belki birileri en azından bunu yapamazdım yapabilirim
teksturi 12

1
Birkaç bayt kaydetmek için iki argüman kabul edebilirsin: codegolf.stackexchange.com/a/153132/77415
user84207

3

Perl 6 , 21 bayt

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

Expanded:

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

Tebrikler, hayır cevabını aldın. 101010!
Rudolf Jelin

@ RudolfL.Jelínek Bu hiçbir şey değil, StackOverflow ve Meta.StackExchange Ben 1337 numaralı kullanıcıyım
Brad Gilbert b2gills

3

Cubix, 33 32 bayt

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

Net form:

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

Çevrimiçi deneyin!

notlar

  • 170'e kadar olan ve bunlara dahil olan girdilerle çalışır, daha yüksek girdiler sonsuz bir döngüye neden olur, çünkü faktörlü değerleri Infinity sayıyı (teknik olarak konuşulursa, pencere nesnesinin yazılabilir, numaralandırılamaz ve yapılandırılamaz bir özelliğidir).
  • Girişler 19 ve üstü için doğruluk kaybedilir, çünkü 2 53'ten (= 9 007 199 254 740 992) daha yüksek sayılar JavaScript’te doğru şekilde saklanamaz.

açıklama

Bu program iki döngüden oluşmaktadır. Birincisi, girişin faktörünü hesaplar, diğeri sonucu rakamlara böler ve bunları birlikte ekler. Sonra toplam yazdırılır ve program sona erer.

başla

İlk önce yığını hazırlamamız gerekiyor. Bu kısım için ilk üç talimatı kullanıyoruz. IP, dördüncü çizgide başlar ve doğuya işaret eder. Yığın boş.

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

Toplamı yığının en altında tutacağız, bu yüzden 0toplamı yığının en altına depolayarak toplamamız gerekir. O zaman a tuşuna basmamız gerekiyor 1, çünkü giriş başlangıçta ondan önceki sayı ile çarpılır. Eğer bu sıfır olsaydı, faktoring de her zaman sıfır verecekti. Son olarak girişi bir tamsayı olarak okuduk.

Şimdi, yığın [0, 1, input]ve IP, dördüncü satırda, dördüncü sütunda, doğuya dönük.

Faktör döngüsü

Bu basit bir halka olduğu çarpar üst yığını (önceki döngü ve giriş sonucunda iki elemanları - n, ve daha sonra giriş azaltır giriş 0 ulaştığı zaman kırılır. $Talimat atlamak için IP neden olur u- Döngü küpün sonraki kısmıdır IP, dördüncü satırda, dördüncü sütunda başlar.

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

^Karakter nedeniyle IP hemen kuzeye doğru hareket etmeye başlar. Ardından uIP döner ve bir tane sağa doğru hareket eder. Altta, başka bir ok var: <IP'yi tekrar işaret ediyor ^. Yığın , yineleme sayısının [previousresult, input-n]olduğu gibi başlar n. Aşağıdaki karakterler döngüde yürütülür:

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

Daha sonra yığın (azalma giriş) üst kontrol edilir 0tarafından !talimat, ve eğer 0,u karakter atlanır.

Rakamları topla

IP küpün etrafına sarılır ve dördüncü satırdaki en son karaktere başlar ve başlangıçta batıya bakar. Aşağıdaki döngü hemen hemen tüm kalan karakterlerden oluşur:

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

Döngü ilk olarak üst öğeyi yığından siler (ki ya 10da ya da 0) ve sonra faktörün sonucunun kalanını kontrol eder. Bu 0azalmışsa, yığının altı (toplam) basılır ve program durur. Aksi takdirde, aşağıdaki talimatlar uygulanır (yığın olarak başlar [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]

Ve döngü factorial/100'a eşit olana kadar tekrar başlar .


3

C, 47 bayt

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

kullanımı:

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 bayt

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

Çevrimiçi deneyin


Str yerine ters keneler kullanabilir misiniz?
nedla2004

2
@ nedla2004 LFaktöriyelinin uzun olması için yeterince büyük olduğu bir zamanlar eklenirdi .
Kade

2

Toplu iş, 112 bayt

@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/aBir değişkenin mevcut değerine uygun şekilde çalışır, bu nedenle normalde bir döngü içinde çalışır. Batch'ın tamsayı tipinin sınırlamaları nedeniyle yalnızca 12'ye kadar çalışır, bu nedenle teoride şunu kabul ederek 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%

Ama bu şekilde delilik yatıyor ... Bu durumda listeyi zor kodlayabilirim (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 bayt

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

Yalnızca n=22kayan nokta doğruluğu sınırlamaları nedeniyle çalışır .


2

Befunge 93 , 56 54 bayt

Kaydedilen 2 bayt tırnak yerine get kullanarak yapmak. Bu, gereksiz beyaz alanı azaltarak ilk 2 çizgiyi 1 üzerinden kaydırmama izin verdi.

Çevrimiçi deneyin!

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

Açıklama:

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

Haklısın. Yeni bir sürüm üzerinde çalışıyorum. Bilginize, quickster.com kullanıyorum, çünkü bulduğum diğerleri yığında yalnızca bir tane olduğunda `` doğru davranmıyordu.
MildlyMilquetoast,

Teşekkürler! Görünüşe göre bu kod yalnızca Befunge-98 versiyonunda düzgün çalışıyor , muhtemelen de put metodundan.
MildlyMilquetoast 24/16

0'ı doğru bir şekilde işleyen 48 bayt
Jo King,

2

Javascript ES6 - 61 54 Bayt

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

EDIT: Teşekkürler Hedi ve ETHproductions 7 bayt tıraş için. Bunu hatırlamak zorundayım t - = - j numara.


1
Güzel cevap! Bir kaç bayt çeşitli şekillerde kaydedebilirsiniz:n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
ETHproductions

@ETHproductions Daha fazla sayıda bayt eval ile kaydedilebilir:n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
Hedi

@Hedi biliyorum, her seferinde bir adım
atıyordum

2

AHK , 60 bayt

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

AutoHotkey yerleşik bir faktoring işlevine sahip değildir ve loop işlevleri, yerleşik değişkenleri için uzun adlara sahiptir. İlk döngü faktördür ve ikincisi rakamları bir araya getirmektir.


2

J, 12 11 bayt

Cole sayesinde 1 byte kurtarıldı!

1#.10#.inv!

Bu sadece bir miktar (uygulanır 1#.(ters kullanılarak rakama kadar) invtaban dönüşümün #.bir baz ile 10(faktöriyel bir)! Tartışmanın).

Test durumları

Not: Son iki test durumu, sonda ile işaretlenmiş gibi bigints x.

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

"."0":Rakamları almak için kullanabilirsiniz
Bolce Bussiere

11 bayt: 1#.,.&.":@!küçük vakalar için de genişletilmiş hassasiyet gerektirir (neden olduğundan emin değil). Ayrıca 11 bayt: 1#.10#.inv!.
cole


1

C, 63 bayt

do...whileDöngü için -3 bayt .

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

Ungolfed ve kullanım:

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

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

F (n) 'yi intvarsayılan olarak tanımlıyor muyuz ?
Mukul Kumar

@MukulKumar bu, C tipi standart olup, eğer bir tip yoksa intvarsayılır.
Karl Napf
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.