계승 숫자 합


25

문제는 숫자 계승의 자릿수를 계산하는 것입니다.


Input: 10
Output: 27

10! = 10 × 9 × ... × 3 × 2 × 1 = 3628800, 그리고 숫자 10의 숫자의 합! 3 + 6 + 2 + 8 + 8 + 0 + 0 = 27입니다

입력은 0보다 큰 정수일 것으로 예상 할 수 있습니다. 출력은 모든 유형이 될 수 있지만, 답변은 코딩 언어의 표준 기반이어야합니다.


테스트 사례 :

10    27
19    45
469   4140
985   10053

NB 일부 언어는 32 비트 정수보다 큰 수를 지원할 수 없습니다. 이러한 언어의 경우 큰 계승을 계산하지 않아도됩니다.

마틴 엔더 덕분에 여기OEIS 링크


이것은 이므로 문자가 가장 짧은 코드가 승리합니다!


예상되는 최대 입력 수는 얼마입니까? R에서 32 비트 정수를 사용하면이 문제를 정확하게 해결할 수 없습니다.n>21
Billywob

1
@Billywob R의 경우 20으로 가면됩니다. 이것을 반영하기 위해 질문을 편집하겠습니다
george

답변:





7

C ++ 11, 58 바이트

이름을 바꾸지 않은 람다는 입력을 수정합니다.

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

내 C ++ 코드가 C 코드 보다 짧은 드문 경우 중 하나입니다 .

더 큰 사례를 지원하려면 C ++ 14로 전환 하고 다음을 사용하십시오.

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

호출 인수에 ull접미사를 제공하십시오.

용법:

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

루비, 63 61 53 38 바이트

manatwork 덕분에 새로운 접근 방식 :

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

늙은:

->n{(1..n).reduce(:*).to_s.chars.map(&:hex).reduce:+}
  • Martin Ender 덕분에 -3 바이트
  • GB 덕분에 -5 바이트

1
오래된 지루한 eval방법 : ->n{eval"#{(1..n).reduce:*}".chars*?+}.
manatwork

6

Pyth, 7 6 바이트

바이트를 절약 해 주신 @Kade에게 감사드립니다.

sj.!QT

온라인으로 사용해보십시오!

Pyth를 사용한 것은 이번이 처음이므로 내 대답이 꽤 골프를 칠 수 있다고 확신합니다.

설명:

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

1
10변수에 할당 T이 할 수 있도록, sj.!QT:)
카데

알았어 고마워! 추가하겠습니다
BookOwl

좋은! ssM`.!6 바이트로도 작업을 수행합니다.
hakr14

5

하스켈, 41 40 바이트

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

사용 예 : f 985-> 10053.

에서 목록을 확인 1하는 x목록 요소의 제품을 계산, 그 문자열 표현으로 바꿀 숫자로 각 문자를 설정하고이를 요약.

편집 : @ Angs는 바이트를 저장했습니다. 감사!


f x=sum$read.pure<$>(show$product[1..x])바이트를 절약
Angs

5

파이썬, 54 바이트

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

반복


난 그냥 보이는이의 약간 더 나쁜 버전 해낸 방법 은 별도의 대답으로 너무 유사. 브라보
osuka_

5

R, 58 53 바이트

편집 : @Jonathan Carroll 덕분에 1 바이트를 저장하고 @Micky T 덕분에 몇 바이트를 절약했습니다.

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

불행히도 32 비트 정수의 경우에만 작동합니다 n < 22. stdin에서 입력을 가져 와서 stdout으로 출력합니다.

더 높은 수준의 정밀도를 원한다면 다음과 같은 외부 라이브러리를 사용해야합니다 Rmpfr.

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

1
나는 당신과 똑같은 대답을 c(x,"")얻었고 vs paste(x): 에서 1 바이트의 이득을 발견했습니다 sum(as.integer(el(strsplit(c(factorial(scan()),""),"")))). 계승 결과를 문자로 강제 변환하고 strsplit두 번째 목록으로 리턴하므로 el여전히 작동하고 첫 번째 목록 요소를 추출합니다.
조나단 캐롤

2
방법은 prod(1:scan())?
MickyT

1
또한 as.double 충분하다
MickyT

@MickyT 감사합니다! 업데이트되었습니다.
Billywob

strtoi짧은 교체로 작동 as.double한다고 생각합니다.
Giuseppe

4

, 8 바이트

$+$*++,a

온라인으로 사용해보십시오!

설명

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

죄송합니다, 실제로 당신 앞에 05AB1E 답변을 게시 할 수있었습니다;).
Magic Octopus Urn

2
@carusocomputing : Hehe. 새로운 언어를 볼 수있는 기회를 얻었습니다 :)
Emigna

1
비 폴리 글롯 코드 골프 답변에 Pip을 사용하는 것 외에는 당신이 처음이라고 생각합니다. : D
DLosc



3

자바 7, 148 바이트

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 질문에 지정된 제한이 없습니다. 9,223,372,036,854,775,807보다 큰 계승을 어떻게 오래 처리해야합니까?
jacksonecac

3

루비, 63 60 53 51 바이트

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

골프를 도와 준 Martin에게 감사합니다.


3

Pushy , 4 바이트

fsS#

명령 행에 입력하십시오 $ pushy facsum.pshy 5. 고장은 다음과 같습니다.

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

3

옥타브, 30 바이트

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

리스트의 곱을 취하여 계승을 계산합니다 [1 2 ... n]. 문자열로 변환하고 48모든 요소에서 뺍니다 (ASCII 코드 0). 마지막으로 그것을 요약합니다 :)


3

bash (seq, bc, fold, jq), 34 33 바이트

확실히 가장 우아하지는 않지만 도전을 위해

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

fold -1바이트를 저장합니다.
Digital Trauma

@DigitalTrauma가 수정되었습니다! 감사
아담

3

C, 58 바이트

이것은 완벽하지 않습니다. 시작시 -1이어야하므로 하나만 작동합니다. 하나의 함수에 두 개의 재귀 함수를 사용하는 것이 좋습니다. 내가 처음 생각했던 것만 큼 쉽지 않았습니다.

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

사용법과 이해할 수있는 형식 :

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

편집 :이 기능을 여러 번 사용할 수 있지만 길이는 62 바이트 인 metode를 찾았습니다.

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

좋은 생각이지만, 하나의 함수를 사용하여 계승을 반환하고 다른 함수를 사용하여 a (b (10))와 같은 숫자 합계를 계산하는 것이 더 짧은 이유를 잘 모르겠습니다. "복귀"라는 단어가 너무 길어서 작동하지 않습니까?
JollyJoker

귀국은 많이 먹는다. 물론 시도합니다. 어쩌면 누군가는 적어도 그 일을 할 수 없었습니다.
teksturi

1
몇 바이트를 절약하기 위해 두 개의 인수를 사용할 수 있습니다. codegolf.stackexchange.com/a/153132/77415
user84207

3

펄 6 , 21 바이트

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

넓히는:

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

축하합니다. 대답이 없습니다. 101010!
RudolfJelin

@ RudolfL.Jelínek 그의에 아무것도, StackOverflow에 , 그리고 Meta.StackExchange I AM 사용자 번호 1337
브래드 길버트는 b2gills

3

Cubix, 33 32 바이트

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

순수한 형태 :

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

온라인으로 사용해보십시오!

노트

  • 최대 170 개의 입력과 함께 작동하며 더 높은 입력은 계승이 Infinity수 (기술적으로 말하자면, 쓰기 불가능하고 열거 불가능하고 구성 불가능한 윈도우 객체의 속성)를 산출하기 때문에 무한 루프 를 발생시킵니다.
  • 2 53 보다 큰 숫자 (= 9 007 199 254 740 992)는 JavaScript에 정확하게 저장할 수 없으므로 입력 19 이상에서는 정확도가 손실됩니다 .

설명

이 프로그램은 두 개의 루프로 구성됩니다. 첫 번째는 입력의 계승을 계산하고 다른 하나는 결과를 숫자로 나누고 함께 더합니다. 그런 다음 합계가 인쇄되고 프로그램이 완료됩니다.

스타트

먼저 스택을 준비해야합니다. 이 부분에서는 처음 세 가지 지침을 사용합니다. IP는 네 번째 줄에서 시작하여 동쪽을 가리 킵니다. 스택이 비어 있습니다.

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

우리는 스택 맨 아래에 합계를 유지하므로 스택 맨 아래에 0합계를 저장하여 합계가되어야합니다. 1입력은 초기에 숫자를 곱하기 때문에 a를 눌러야 합니다. 이것이 0이면 계승은 항상 0도 산출합니다. 마지막으로 입력을 정수로 읽습니다.

이제 스택이 [0, 1, input]있고 IP가 네 번째 줄, 네 번째 열에 있으며 동쪽을 가리 킵니다.

계승 루프

이것은 스택의 상위 2 개 요소 (이전 루프와 입력-n의 결과를 곱한 다음 입력을 줄입니다)의 간단한 루프입니다. 입력이 0에 도달하면 중단됩니다. $명령으로 인해 IP가 u- 루프는 큐브의 다음 부분이며 IP는 네 번째 줄, 네 번째 열에서 시작합니다.

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

때문에의 ^문자의 IP 즉시 북쪽으로 이동을 시작합니다. 그런 다음 uIP를 돌리고 오른쪽으로 이동합니다. 맨 아래에는 또 다른 화살표가 있습니다. <IP가 다시를 가리 킵니다 ^. 스택은로 시작하며 [previousresult, input-n]여기서 n반복 횟수는입니다. 루프에서 다음 문자가 실행됩니다.

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

그런 다음 스택의 상단 (감소 된 입력)을 명령 에 0의해 확인하고이 값 !0인 경우 u문자를 건너 뜁니다.

숫자 합

IP는 입방체를 감싸며 네 번째 줄의 마지막 문자로 끝나고 처음에는 서쪽을 가리 킵니다. 다음 루프는 거의 모든 나머지 문자로 구성됩니다.

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

루프는 먼저 스택에서 최상위 항목 ( 10또는 0)을 삭제 한 다음 계승 결과의 남은 항목을 확인합니다. 이 값이로 줄어들 0면 스택 맨 아래 (합)가 인쇄되고 프로그램이 중지됩니다. 그렇지 않으면 다음 명령어가 실행됩니다 (스택이로 시작됨 [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]

그리고 factorial/100이 될 때까지 루프가 다시 시작됩니다 .


3

C, 47 바이트

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

용법:

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

배치, 112 바이트

@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/a변수의 현재 값에서 작동하므로 루프 내에서 정상적으로 작동합니다. Batch의 정수 유형의 한계로 인해 최대 12까지만 작동하므로 이론적으로 다음과 같이 가정하여 바이트를 절약 할 수 있습니다 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%

그러나 그 방법은 광기입니다 ...이 경우 목록을 하드 코딩 할 수도 있습니다 (97 바이트).

@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

자바 스크립트 (ES6), 50 바이트

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

n=22부동 소수점 정확도 제한으로 만 작동합니다 .


2

빌 펀지 93 , 56 54 바이트

저장된 2 바이트는 따옴표 대신 get을 사용합니다. 이를 통해 상단 2 줄을 1 위로 이동하여 불필요한 공백을 줄입니다.

온라인으로 사용해보십시오!

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

설명:

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

당신이 올바른지. 새 버전으로 작업 중입니다. 참고로, 나는 quickster.com을 사용하고 있습니다.
MildlyMilquetoast

감사! 이 코드는 Befunge-98 버전 에서만 제대로 작동하는 것 같습니다. 아마도 put 메소드 때문일 것입니다.
MildlyMilquetoast

0을 올바르게 처리하는 48 바이트
Jo King

2

자바 스크립트 ES6 - 61 54 바이트

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

편집 : 7 바이트를 깎아 준 Hedi와 ETHproductions에게 감사드립니다. 나는 t-=-j 속임수를 기억해야 할 것이다.


1
좋은 대답입니다! 다양한 방법으로 몇 바이트를 저장할 수 있습니다.n=>{a=_=>!_||_*a(~-_);t=0;for(j of''+a(n))t-=-j;return t}
ETHproductions

@ETHproductions 더 많은 바이트를 eval로 저장할 수 있습니다 :n=>eval(`for(j of''+(a=_=>!_||_*a(~-_))(n,t=0))t-=-j`)
Hedi

내가 아는 @Hedi, 나는 한 단계 :-) 한 번에 복용 한
ETHproductions

2

AHK , 60 바이트

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

AutoHotkey에는 내장 계승 함수가 없으며 루프 함수에는 내장 변수의 긴 이름이 있습니다. 첫 번째 루프는 계승이며 두 번째 루프는 숫자를 더합니다.


2

J, 12 11 바이트

콜 덕분에 1 바이트를 절약했습니다!

1#.10#.inv!

이것은 단순히 합 (적용 1#.(역 사용 자리) inv기반 변환을 #.하는 염기 10계승 (의) !인수를).

테스트 사례

참고 : 마지막 두 테스트 사례는 후행으로 표시되는 bigint x입니다.

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

당신은 "."0":숫자를 얻을 수 있습니다
Bolce Bussiere

11 바이트 : 1#.,.&.":@!작은 경우에도 확장 정밀도가 필요합니다 (이유가 확실하지 않습니다). 또한 11 바이트 : 1#.10#.inv!.
cole


1

C, 63 60 바이트

do...while루프에 -3 바이트 .

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

언 골프 및 사용법 :

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

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

int기본적 으로 f (n)을 정의 합니까?
Mukul Kumar

@MukulKumar 이것은 C에서 표준이며, 유형이 없으면 int가정됩니다.
Karl Napf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.