반복했다! 계승!


34

계승 찾기 와 혼동하지 마십시오 !

소개

정수의 계승을 n계산할 수있다

n!=n×(n1)×(n2)×(...)×2×1

이것은 비교적 쉽고 새롭지 않습니다. 그러나 계승가 확장 될 수 이중 계승 ,되도록 짝수 및 대 홀수의 경우 입니다. 그러나 우리는 이중 계승으로 제한되지 않습니다. 예를 들어 또는 또는 에 따라 시작 값.

n!!=n×(n2)×(n4)×(...)×4×2
n!!=n×(n2)×(n4)×(...)×3×1
n!!!=n×(n3)×(n6)×(...)×6×3
n!!!=n×(n3)×(n6)×(...)×5×2
n!!!=n×(n3)×(n6)×(...)×4×1

요약하면 : 여기서 또는 일반 영어 : 기본 수에서 계승 수를 반복적으로 빼고 모든 양의 정수를 곱합니다.

n!(k)={1if n=0nif 0<nkn((nk)!(k))if n>k
n!(k)=n!!k

도전

음수가 아닌 정수에 대해 반복되는 계승을 계산하는 함수를 작성하십시오.

입력

어느 한 쪽

  • 음수가 아닌 10 진 정수 다음에 느낌표가 1 개 이상 포함 된 문자열 예 "6!"또는 "9!!""40!!!!!!!!!!!!!!!!!!!!".

또는

  • 두 개의 정수로 표시되는 동일한 값 : 음이 아닌 기본 값 하나와 계승 계수를 나타내는 양수 값 기본 I / O 규칙의 형식에 따라 수행 할 수 있습니다.

산출

상기 계산의 결과.

도전 비고

  • 0!1정의에 의해 동일 합니다. 코드가이를 설명해야합니다.
  • 계승 카운트는 이 범위 밖의 으로 제한되며 , 무엇이든 자유롭게 출력 할 수 있습니다. 이외에도에서 이 규칙에 대한 유일한 예외이다.
    0<factorial countbase value
    0!

Input                              Output

3!!!                               3
0!                                 1
6!                                 720
9!!                                945
10!!!!!!!!                         20
40!!!!!!!!!!!!!!!!!!!!             800
420!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  41697106428257280000000000000000

ungolfed Python 구현으로 사용해보십시오 : 온라인으로 사용해보십시오!

총론


6
예제 목록에 0!있지만 도전 과제는 계승 카운트가 기본 값보다 작거나 같다고 말합니다.
Jonathan Allan

1
그렇지 않겠 어 !!! 제로? n * (n-3) = 3 * (3-3) = 0.
ouflak

2
@ouflak 1처럼 작동하면 실제로는 그렇지 않습니다. 1과 비슷합니다! = 1. 2 !! = 2. 3 !!! = 3. 재귀가 끝났으므로 계산이 없습니다. 제품에 0이 없거나 모든 단일 계승은 결국 0으로 떨어집니다.
V. Courtois

4
3!!!!!!!정의되지 않아야합니다 3. 답을 산출해야합니다 . 1!!=1(정의되지 않음) 과 동일 합니다. 또한 입력 사양에 따르면 항상 하나 이상이 !있으므로 첫 번째 예 3는 사양에 맞지 않습니다.
Greg Martin

3
@ FabianRöling : 그러나 이것이 아닙니다. (3!)!대신 계승에서 항을 제거 하는 것이 아닙니다 . 오해의 소지가있는 이름입니다. 체인에서 팩토리얼 함수를 반복적으로 적용한다고 가정하고 실제로 무엇인지 확인하기 위해주의 깊게 읽어야했습니다. 다행히도 그 질문은 그것을 명확하게 설명합니다. 더 나은 이름은 보폭 계급 또는 단계 계승 또는 무언가 일 수 있습니다.
Peter Cordes

답변:



13

ArnoldC , 702 698634 바이트

LISTEN TO ME VERY CAREFULLY f
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE n
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE p
GIVE THESE PEOPLE AIR
HEY CHRISTMAS TREE r
YOU SET US UP 1
HEY CHRISTMAS TREE c
YOU SET US UP 0
STICK AROUND n
GET TO THE CHOPPER r
HERE IS MY INVITATION r
YOU'RE FIRED n
ENOUGH TALK
GET TO THE CHOPPER n
HERE IS MY INVITATION n
GET DOWN p
ENOUGH TALK
GET TO THE CHOPPER c
HERE IS MY INVITATION 0
LET OFF SOME STEAM BENNET n
ENOUGH TALK
BECAUSE I'M GOING TO SAY PLEASE c
GET TO THE CHOPPER n
HERE IS MY INVITATION 0
ENOUGH TALK
YOU HAVE NO RESPECT FOR LOGIC
CHILL
I'LL BE BACK r
HASTA LA VISTA, BABY

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

의사 코드로 번역 :

f(n,p) {
  r=1;
  c=0;
  while (n) {
    r=r*n;
    n=n-p;
    c=n<0;
    if (c) n=0;
  }
  return r;
}

참고 : ArnoldC에는 16 비트 부호있는 정수의 한 가지 유형의 데이터 만 있습니다. 따라서 나는 그 420!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!사건을 시험 할 수 없다 .


psuedocode가 궁금합니다. 변수 'c'는 무엇입니까?
ouflak

@ouflak 나는 대답을 두 번 편집하여 잊어 버렸습니다. c변수 실제로 간의 비교 값을 저장 n0.
찰리

+1하고 LUA 답변을 위해 ( 'c'빼기) 빌 렸습니다.
ouflak

12

젤리 , 4 바이트

RṚmP

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

방법? 과 주어지면 먼저 범위 ( )을 생성 한 다음 이 범위의 모든 요소 ( ), 마지막 사용하여 곱합니다 .nkn,,1k th n , n - k , n - 2 k , , n - n / k kRṚmkthn,nk,n2k,,nn/kkP


잘 작동하고 결국 매우 간단합니다. 나는 젤리를 전혀 모른다. 그러나 적어도 그것은 좋아 보인다 :)
V. Courtois

1
@ V.Courtois 과 주어지면 먼저 범위 ( )을 생성 한 다음 이 범위의 모든 요소를 유지합니다 ( ), 마지막 사용하여 곱합니다 . 간단한 접근 방식. 편집 : 나는이 설명을 답변에 추가했습니다. k n , , 1 k th n , n - k , n - 2 k , , n - n / k knkn,,1RṚmkthn,nk,n2k,,nn/kkP
Mr. Xcoder

응 고마워 언젠가 나는이 언어로 골프를하고 싶어서 모나드, 다이어 드 등을 배워야 할 것입니다.
V. Courtois

CJam처럼 보이는 대안 : r1mP.
Outgolfer Erik

1
@KyeWShi Jelly에는 자체 코드 페이지 가 있으므로 포함 된 256 자 각각은 1 바이트로 인코딩됩니다.
Mr. Xcoder


7

하스켈 , 21 바이트

n%a=product[n,n-a..1]

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

내장 제품 기능을 단계적 범위 열거와 결합하면 재귀 적으로 코딩 할 수있는 것 (바이트를 저장하는 flawr을 포함하여)을 능가합니다.

22 바이트

n%a|n<1=1|m<-n-a=n*m%a

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

다음과 같은 문자열 형식으로 입력을받는 솔루션 9!!이 있습니다. 더 흥미 롭습니다.

42 바이트

(\[(n,a)]->product[n,n-length a..1]).reads

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


2
난 당신의 재귀 솔루션을 단축 할 수 있다고 생각n%a|n<1=1|m<-n-a=n*m%a
flawr을



5

공백 , 91 바이트

[S S S T    N
Push_1][S N
S _Duplicate_1][S N
S _Duplicate_1][T   N
T   T   _Read_STDIN_as_integer_(base)][T    T   T   _Retrieve_base][S S S N
_Push_0][T  N
T   T   _Read_STDIN_as_integer_(factorial)][N
S S N
_Create_Label_LOOP][S N
S _Duplicate_base][S S S T  N
_Push_1][T  S S T   _Subtract][N
T   T   S N
_If_negative_jump_to_Label_PRINT_RESULT][S N
S _Duplicate_base][S T  S S T   S N
_Copy_0-based_2nd_(result)][T   S S N
_Multiply][S N
T   _Swap_top_two][S S S N
_Push_0][T  T   T   _Retrieve_factorial][T  S S T   _Subtract][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_PRINT_RESULT][S N
N
_Discard_top][T N
S T _Print_result_as_integer]

문자 S(공백), T(탭) 및 N(줄 바꾸기)가 강조 표시로만 추가되었습니다.
[..._some_action]설명으로 만 추가되었습니다.

온라인으로 시도하십시오 (원시 공백, 탭 및 줄 바꾸기 만).

의사 코드의 설명 :

Integer result = 1
Integer base = STDIN as integer
Integer factorial = STDIN as integer
Start LOOP:
  If(base <= 0):
    Call function PRINT_RESULT
  result = result * base
  base = base - factorial
  Go to next iteration of LOOP

function PRINT_RESULT:
  Print result as integer to STDOUT


4

펄 6 , 22 바이트

{[*] $^a,*-$^b...^1>*}

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

첫 번째 입력에서 시작하여 범위의 곱을 반환 1하고 마지막 숫자를 제외하고 아래에 올 때까지 두 번째만큼 감소하는 익명 코드 블록입니다 . 이것은 0제품 별 감소의 기본 사례가 1이므로 출력은 1이므로 작동합니다.


4

05AB1E , 10 8 7 바이트

ݦRIιнP

두 개의 분리 된 입력으로 입력 : 첫 번째 입력 base; 두 번째 입력은 factorial입니다.

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

@ Mr.Xcoder 덕분에 -2 바이트 . @JonathanAllan
덕분에 -1 바이트 .

설명:

Ý        # Create a list in the range [0, (implicit) base-input]
 ¦       # And remove the first item to make it the range [1, base]
         # (NOTE: this is for the edge case 0. For the other test cases simply `L` instead
         #  of `ݦ` is enough.)
  R      # Reverse this list so the range is [base, 1]
   Iι    # Uninterleave with the second input as step-size
         #  i.e. base=3, factorial=7: [[3],[2],[1],[],[],[],[]]
         #  i.e. base=10, factorial=8: [[10,2],[9,1],[8],[7],[6],[5],[4],[3]]
         #  i.e. base=420, factorial=30: [[420,390,360,...,90,60,30],[419,389,359,...],...]
     н   # Only leave the first inner list
      P  # And take the product of its values
         # (which is output implicitly as result)

원래 10 바이트 답변 :

L0KD¤-IÖÏP

두 개의 분리 된 입력으로 입력 : 첫 번째 입력 base; 두 번째 입력은 factorial입니다.

온라인으로 시도 하거나 모든 테스트 사례를 확인하십시오 .

설명:

L           # Create a list in the range [1, (implicit) base-input]
 0K         # Remove all 0s (edge case for input 0, which will become the list [1,0])
   D        # Duplicate this list
    ¤       # Get the last value (without popping)
            # (could also be `Z` or `¹` for max_without_popping / first input respectively)
     -      # Subtract it from each item in the list
      IÖ    # Check for each if they're divisible by the second factorial-input
        Ï   # In the list we copied, only leave the values at the truthy indices
         P  # And take the product of those
            # (which is output implicitly as result)

1
이 6 바이트 : LR²ιнP( 온라인으로 사용해보십시오! )는 0을 제외한 모든 테스트 사례에 적용됩니다.
Mr. Xcoder

그러나 0 사례는 최대 2 바이트로 고정 될 수 있다고 생각합니다. 그것을 고치는 방법을 알아 내면 그것을 취할 수 있습니다 :) 편집 : 아마도 LR²ιн0KP8 바이트입니까?
Mr. Xcoder

@ Mr.Xcoder 멋진 답변입니다! 주어진 단계에서 인터리브를 사용하지 마십시오. :)
Kevin Cruijssen

0K0!사양에 의해 유효하지 않은 입력이므로 불필요 합니다 (예제에 포함되어 있음에도 불구하고)- 이것에 대해 언급 했습니다.
Jonathan Allan

1
... 입력 도메인에 있으면 바이트를 저장합니다. 0!ݦRXιнP
Jonathan Allan

4

x86-64 기계 코드, 12 바이트

동일한 기계 코드는 32 비트 모드에서, 16 ​​비트 모드에서 16 비트 정수에 대해 동일한 작업을 수행합니다.

이 인수로 호출하는 기능입니다 n=RCX, k=ESI. 32 비트의 리턴 값 EAX.

실제 args를 올바른 레지스터로 가져 오기 위해 더미 args가있는 x86-64 System V 호출 규칙을 사용하여 C에서 호출 할 수 있습니다. uint32_t factk(int, uint32_t k, int, uint64_t n); 1- 오퍼랜드 mul클로버 RDX 때문에 Windows x64를 사용할 수 없었으며 REX 접두사가 R8 / R9에 액세스하는 것을 원하지 않습니다. nJRCXZ가 작동하지만 32 비트가 아닌 모든 32 비트에는 가비지가 없어야합니다.

NASM 리스팅 (상대 주소, 머신 코드, 소스)

 1                         factk:
 2 00000000 6A01             push 1
 3 00000002 58               pop rax             ; retval = 1
 4 00000003 E306             jrcxz  .n_zero      ; if (n==0) return
 5                         .loop:                ; do {
 6 00000005 F7E1              mul   ecx            ; retval *= n  (clobbering RDX)
 7 00000007 29F1              sub   ecx, esi       ; n -= k
 8 00000009 77FA              ja   .loop         ; }while(sub didn't wrap or give zero)
 9                         .n_zero:
10 0000000B C3               ret

0xc = 12 바이트


또는 n=0특수한 경우 를 처리 할 필요가없는 경우 10 바이트 를 빼고 jrcxz.

표준 계승 loop의 경우 sub / ja 대신 2 바이트를 사용하지만 그렇지 않으면 정확히 동일한 코드를 사용합니다.


패스 테스트 호출 argck으로 n하드 코딩.

align 16
global _start
_start:
  mov  esi, [rsp]
;main:
  mov  ecx, 9
  call factk

  mov  esi, eax
  mov  edx, eax
  lea  rdi, [rel print_format]
  xor  eax, eax
extern printf
  call printf
extern exit
  call exit

section .rodata
print_format: db `%#x\t%u\n`

```




3

자바 10, 44 바이트

f->b->{int r=1;for(;b>0;b-=f)r*=b;return r;}

계승을 첫 번째 입력으로, 기본을 두 번째로 사용합니다.

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

제한된 정수 범위 (32 비트)로 인해 가장 큰 테스트 사례에서는 위의 작업이 작동하지 않습니다. 이 문제를 해결하려면 우리가 사용할 수 BigIntegers있는 동시 되어 정확하게 크기를 두 배로 - 88 79 바이트를 :

f->b->{var r=f.ONE;for(;b.signum()>0;b=b.subtract(f))r=r.multiply(b);return r;}

@ OlivierGrégoire 덕분에 -9 바이트 .

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

설명:

f->b->{       // Method with two integer parameters and integer return-type
  int r=1;    //  Result-integer, starting at 1
  for(;b>0;   //  Loop as long as the base is still larger than 0
      b-=f)   //    After every iteration: decrease the base by the factorial
    r*=b;     //   Multiply the result by the base
  return r;}  //  Return the result


@ OlivierGrégoire Np, 감사합니다! :)
Kevin Cruijssen



2

MathGolf , 7 6 바이트

╙╒x%ε*

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

0을 처리하는 영리한 방법을 찾았습니다! 다른 테스트 사례를 변경하지 않고 입력을 k n(역순)으로 가져 와서 암시 적 팝에 도움이됩니다.

설명

╙        maximum of two elements (pops largest of k and n,
         which is n for every valid case except 0!, where 1 is pushed)
 ╒       range(1,n+1)
  x      reverse int/array/string
   %     slice every k:th element
    ε*   reduce list with multiplication

2

첨부 , 21 19 바이트

${x<y∨x*$[x-y,y]}

온라인으로 사용해보십시오! 매우 직접적인 재귀 구현. (참고 : true1산술 연산에서 사용할 수 있으므로 본질적 으로 1입니다.) 이것은 유니 코드 연산자를 사용하여 바이트 (1)를 절약하는이 사이트에 대해 작성한 몇 가지 프로그램 중 하나입니다.

대안

20 바이트 : ${x<y or x*$[x-y,y]}

21 바이트 : Prod@${{_%y=x%y}\1:x}

27 바이트 : ${x*[`1,$][x>y][x-y,y]∨1}

27 바이트 : ${If[x>y,x*$[x-y,y],_or 1]}

27 바이트 : ${x*[`1,$][x>y][x-y,y]or 1}

29 바이트 : ${If[x>y,x*$[x-y,y],_+not _]}


2

, 92 73 61 바이트

fn f(n:i128,k:i128)->i128{if n<=0{return 1}return n*f(n-k,k)}

나는 방금 녹을 배우기 시작했기 때문에 이것이 더 짧을 수 있다고 확신합니다. 내가 배우면서 업데이트됩니다. i128마지막 테스트를 계산하려면 반환 값이 있어야합니다 .

편집 : 재귀가 짧습니다.

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

자체 테스트를 추가하거나 기존 테스트 중 하나를 편집 할 수 있습니다.


2

q , 59 57 55 53 바이트

{prd 2+(&)1_i=last i:("J"$x(&)not[n])#(!)sum n:"!"=x}

설명:

q)x:"12!!" / let our input be 12!!, assign to x
q)sum n:"!"=x / count "!"s
2i
q)(!)sum n:"!"=x / (!)m -> [0,m)
0 1
q)("J"$x(&)not[n]) / isolate the number in input
12
q)("J"$x(&)not[n])#(!)sum n:"!"=x / x#y means take x items from list y, if x>y, circle around
0 1 0 1 0 1 0 1 0 1 0 1
q)i:("J"$x(&)not[n])#(!)sum n:"!"=x / assign to i
q)i
0 1 0 1 0 1 0 1 0 1 0 1
q)(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / take last elem of i and see which are equal in i
010101010101b
q)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / drop first elem
10101010101b
q)(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / indices of 1b (boolean TRUE)
0 2 4 6 8 10
q)2+(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / add 2 across array
2 4 6 8 10 12
q)prd 2+(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / product across array
46080

여기에 k (동일한 논리), 42 41 바이트 의 버전이 있습니다

{*/2+&1_i=last i:("J"$x@&~:n)#!+/n:"!"=x}

사이트에 오신 것을 환영합니다! 줄 앞에 4 칸 띄우거나 삼중 백틱으로 묶어서 할 수있는 코드 형식을 게시물에 추가했습니다.
밀 마법사

@ SriotchilismO'Zaic 감사 :-)
낙서

1
설명과 TIO 같은 온라인 통역사에 대한 링크를 추가하는 것이 좋습니다 . 코드 전용 답변은 일반적으로 자동으로 품질이 낮은 것으로 표시됩니다.
mbomb007

@ mbomb007 흥미로운. 봇 신고 답변이 있습니까? 품질이 낮은 제출물은 어떻게 되나요? 곧 업데이트하겠습니다!
낙서

예, 봇이 있습니다. StackExchange는 봇을 사용하여 잠재적 인 스팸 및 품질이 낮은 답변을 찾습니다. 평판이 높은 사람은 검토 대기열을 볼 수 있습니다. meta.stackexchange.com/a/161391/285610
mbomb007


1

레티 나 , 66 바이트

^0
1
\d+
*!,
+`(!+)(!+),\1$
$1$2,$2,$1
!+$
1
+`(!+),(\d+)
$.($2*$1

온라인으로 사용해보십시오! 더 빠른 테스트 사례가 포함되어 있습니다. 느낌표가없는 Mauls 숫자. 설명:

^0
1

수정하십시오 0!.

\d+
*!,

n단항으로 변환 하고 구분 기호를 추가하십시오.

+`(!+)(!+),\1$
$1$2,$2,$1

while k에서 반복적으로 빼고 결과를 수집합니다.nn>k

!+$
1

교체 k1(십진수).

+`(!+),(\d+)
$.($2*$1

각 중간 값을 차례로 곱하여 10 진수로 변환합니다.




1

넷째 (gforth) , 50 바이트

: f 1 1 2over / 1+ 0 do 2over i * - 1 max * loop ;

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

코드 설명

: f                \ start a new word definition
  1 1              \ add placeholder and accumulator to stack
  2over / 1+       \ get the number of times to run the loop (num/factorial + 1)
  0 do             \ start loop from 0 to num/factorial
    2over          \ copy num and factorial to the top of the stack
    i * -          \ get the current number to multiply by (num - factorial * i)
    1 max          \ make sure it can't be 0 or negative [set to 1 if it is]
    *              \ multiply accumulator by result
  loop             \ end loop
;                  \ end the word definition           



1

가이아 , 6 바이트

…)¦v%Π

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

입력을 받아 같은 n, k, 입력 있도록 3 4할 것입니다 3!!!!.

…	 push [0...n-1], or [] if n == 0
 )¦	 increment each value (does nothing if [])
   v	 reverse list
    %	 take every k'th element
     Π	 product; product([]) = 1.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.