고조파 계열의 정확한 부분 합


15

도전

양의 정수가 주어지면 N첫 번째 N역수 의 합을 정확한 분수로 출력합니다 . 이는 분자와 분모를 나타내는 일관된 순서로 정수 쌍으로 표시됩니다.

규칙

  • 출력이 정확해야합니다.

  • 출력은 분자와 분모를 나타내는 일관된 순서로 정수 쌍이어야합니다.

  • 정수가 아닌 숫자 유형 (내장 또는 라이브러리)의 사용은 금지됩니다.

    • 설명 / 예외 : 정수가 아닌 숫자 유형은 사용, 계산 및 반환 된 모든 값이 정수 인 경우에만 괜찮습니다 (예 : 언어는 기본적으로 합리적인 숫자를 사용하지만 답변에는 정수 산술 만 사용합니다)
  • 출력은 가능한 한 줄여야합니다. ( 3/2괜찮아요 6/4)

  • 표준 허점 은 금지되어 있습니다.

  • 제출물은 최소 20 개 또는 이 메타 중 더 높은 입력에 대해 작동해야합니다 .

테스트 사례

1: 1/1
2: 3/2 (1/1 + 1/2)
3: 11/6 (1/1 + 1/2 + 1/3)
4: 25/12 etc.
5: 137/60
6: 49/20
20: 55835135/15519504
56: 252476961434436524654789/54749786241679275146400
226: 31741146384418617995319820836410246588253008380307063166243468230254437801429301078323028997161/5290225078451893176693594241665890914638817631063334447389979640757204083936351078274058192000

테스트 케이스 생성 (Python 3)

import fractions
def f(x):
    return sum(fractions.Fraction(1,i) for i in range(1,x+1))

마찬가지로 이 문제이 문제 .

분자는 OEIS A001008 이고 분모는 OEIS A002805 입니다.




인가 gcd는 "내장 기능"당신의 언어를 제공하는 경우?
Chas Brown

@ChasBrown gcd및 기타 내장 함수는 괜찮습니다. 합리적 / 분수 유형은 허용되지 않습니다.
pizzapants184

1
@JoKing 정수만 사용하는 한 숫자가 합리적인 유형이면 좋습니다. 질문을 업데이트하겠습니다.
pizzapants184

답변:


8

파이썬 2 , 80 79 바이트

D=1;N=n=0;exec"n+=1;y=N=N*n+D;x=D=D*n;"*input()
while y:x,y=y,x%y
print N/x,D/x

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

분자와 분모를 인쇄합니다.

예이! MathJax 지원 !!!! 하나는 다음을 관찰합니다.

i=1n1i=i=1nn!n!i=i=1nn!in!

그런 다음에 대한 재귀 생각 에 긍정적 umerator :nN

i=1n+1(n+1)!i=(n+1)i=1nn!i+(n+1)!n+1=(n+1)i=1nn!i+n!

그리고 D분모 생각을 도울 수 없습니다 ! 재귀 적으로도; 따라서 .n!exec

while루프 에서 GCD 계산으로 Reduced Fraction Piper를 지불해야합니다 . 그리고 우리는 끝났습니다.


7

젤리 , 10 바이트

!:RS,!:g/$

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

작동 원리

!:RS,!:g/$  Main link. Argument: n

!           Compute n!.
  R         Range; yield [1, ..., n].
 :          Divide n! by each k in [1, ..., n].
   S        Take the sum. Let's call it s.
     !      Compute n! again.
    ,       Pair; yield [s, n!].
      :g/$  Divide [s, n!] by their GCD.

5

J , 16 바이트

!(,%+.)1#.!%1+i.

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

예제 실행

f =: !(,%+.)1#.!%1+i.
f 6x
   20 49
f 20x
   15519504 55835135
f 56x
   54749786241679275146400 252476961434436524654789

작동 원리

!(,%+.)1#.!%1+i.    NB. Tacit verb
            1+i.    NB. 1 to n inclusive
          !%        NB. Divide factorial by 1 to n
       1#.          NB. Sum i.e. numerator (not reduced)
!                   NB. Factorial i.e. denominator (not reduced)
 (,%+.)             NB. Divide both by GCD

분수 유형을 사용하는 J , 9 바이트

1#.1%1+i.

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

J는 나눌 수없는 경우 int-int 나누기에 대한 분수를 제공합니다.




시겠습니까 2 x:1#.1%1+i.유효한 답으로 간주, 또는이 합리적 유형의 잘못된 사용이다?
cole

5

05AB1E , 10 바이트

!DIL÷O)D¿÷

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

다른 모든 항목과 동일한 방법을 사용합니다. 출력 형식은 [denominator, numerator]입니다.

!DIL÷O)D¿÷   Full program. Let's call the input I.
!D           Push the factorial twice to the stack. STACK: [I!, I!]
  IL         Range from 1 to I. STACK: [I!, I!, [1 ... I]]
    ÷        Vectorized integer division. STACK: [I!, [I! / 1, I! / 2, ..., I! / I]]
     O       Sum. STACK: [I!, I! / 1 + I! / 2 + ... + I! / I]
      )      Wrap stack. STACK: [[I!, I! / 1 + I! / 2 + ... + I! / I]]
       D     Duplicate. STACK: [[I!, I! / 1 + ... + I! / I], [I!, I! / 1 +... + I! / I]]
        ¿    GCD. STACK: [[I!, I! / 1 + ... + I! / I], gcd(I!, I! / 1 +... + I! / I)]
         ÷   Vectorized integer division. 


3

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

를 반환 [numerator, denominator]합니다.

f=(n,a=0,b=1)=>n?f(n-1,p=a*n+b,q=b*n):b?f(0,b,a%b):[p/a,q/a]

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

어떻게?

이 방법은 @ChasBrown의 Python answer 와 유사합니다 .

aba=0b=1

aan+bbbnnn1

n=0

(a,b)(p,q)agcd(a,b)

abbamodb

b=0

p/aq/




2

C ++ 17 (gcc) , 108 바이트

정수 산술 만 사용하십시오.

#import<random>
int f(int x,long&n,long&d){n=0;d=1;int
a;while(n=n*x+d,d*=x,a=std::gcd(n,d),n/=a,d/=a,--x);}

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


C ++ 17 (gcc) , 108 바이트

#import<random>
int f(long&n){double a=0;long
d=1;while(d*=n,a+=1./n,--n);n=a*d+.5;n/=a=std::gcd(n,d);d/=a;}

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

아래와 동일하지만 C ++ 17을 사용하십시오 std::gcd.


C ++ (gcc) , 109 바이트

#import<regex>
int f(long&n){double a=0;long
d=1;while(d*=n,a+=1./n,--n);n=a*d+.5;n/=a=std::__gcd(n,d);d/=a;}

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

C ++은 기본 bigint를 지원하지 않기 때문에 확실히 오버플로 n>20됩니다.

요구 사항 :

  • gcc는 더 이상 사용되지 않습니다 import.
  • gcc 's std::__gcd.
  • -O0그렇지 않으면 컴파일러가 최적화합니다 d/=a.
  • 적어도 64 비트 long.

설명:

  • d=n!,a=H
  • 라운드 a*d가까운 변환하여 정수 a*d+.5long, 그리고 할당 n. 이제 n/d출력입니다.
  • 로 분수를 간단히합니다 std::__gcd.

(1 문자 이하) auto a=0.대신 사용할 수 없습니까 double a=0?
Dan M.

그렇습니다. 그리고 루프에서 하나 더 바이트 : 106 바이트
movatica


2

MATL, 13 바이트

:tptb/sht&Zd/

MATL Online에서 사용해보십시오

@Dennis 'Jelly answer 에서 사용 된 것과 동일한 방법 입니다.

:t    % Range from 1 to n, duplicate. 
pt    % Take the product of that (= factorial), duplicate that too.     
b/    % Bring the range to top of stack, divide factorial by each element    
sh    % Sum those. Concatenate factorial and this into a single array.     
t&Zd/ % Compute GCD of those and divide the concatenated array elements by the GCD.     

(암시 적 출력, 분모를 먼저 인쇄 한 다음 분자를 인쇄합니다.)

부동 소수점 부정확성은 중간 값이 너무 커서 n = 20에서 작동하지 않음을 의미합니다. 테스트 케이스 출력이 오타 인 것처럼 보이며 n = 20에 대한 다른 답변과 동일한 답변을 반환합니다.

다음은 정수 유형 보존 버전 (25 바이트)입니다.

25 바이트, 최대 43 개 입력

O1i:3Y%"t@*b@*b+wht&Zd/Z}

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

숫자를 uint64연산하기 전에 캐스트하고 루프에서 prod또는 을 사용하지 않고 명시 적으로 산술을 수행합니다 sum. 더 중요한 것은 부분 반복자와 분모를 각 반복이 끝날 때마다 단계마다 GCD로 나눕니다. 이것은 입력 범위를 증가시켜 n최대 43까지 허용 합니다. 코드의 일부는 @Chas Brown의 Python 답변을 기반으로합니다.

계승 대신 LCM을 사용하는 대체 (원본) 방법 :

16 15 바이트

:t&Zmtb/sht&Zd/

MATL Online에서 사용해보십시오


1

Excel VBA, 141 바이트

[A1]콘솔 에서 입력 및 출력을받습니다.

s="=If(Row()>A$1,":[B:B]=s+"1,Row())":l=[LCM(B:B)]:[C:C]=s &"0,"&l &"/B1)":g=[GCD(LCM(B:B),SUM(C:C))]:?Format([Sum(C:C)]/g,0)"/"Format(l/g,0)

Ungolfed 및 댓글 달기

Sub HarmonicSum(n)
    [A1] = n                            ''  Pipe input
    s = "=IF(ROW()>A$1,"                ''  Hold the start of formulas
    [B1:B40] = s + "1,ROW())"           ''  Get series of numbers 1 to N, trailing 1s
    l = [LCM(B1:B40)]                   ''  Get LCM
    [C1:C40] = s & "0," & l & "/B1)"    ''  Get LCM/M for M in 1 to N
    g = [GCD(LCM(B1:B40),SUM(C1:C40))]  ''  Get GCD
                                        ''  Format and print output
    Debug.Print Format([Sum(C1:C40)] / g, 0); "\"; Format(l / g, 0)
End Sub


1

Stax , 11 바이트

ó╢Δ'åç4}ú┌7

실행 및 디버깅

설명:

우리는 계산하고 싶습니다 :

나는=11나는

나는

나는=1나는=나는=1나는

우리는 만들 수 있습니다 =!, 우리는 :

나는!=1나는|×!나는=!나는

그래서 우리는 :

나는=11=나는=1!나는!
|Fx{[/m|+L:_m Full program
|F            Factorial
  x           Push input again
   {  m       Map over range [1, n]
    [           Copy the factorial
     /          Divide factorial by current value
       |+     Sum
         L    Listify stack, top gets first element
          :_  Divide both values by gcd
            m Print each followed by newline

1

APL (NARS), 56 자, 112 바이트

{⍵=1:⊂1 1⋄{(r s)←⍺⋄(i j)←⍵⋄m÷∨/m←((r×j)+s×i),s×j}/1,¨⍳⍵}

테스트:

  f←{⍵=1:⊂1 1⋄{(r s)←⍺⋄(i j)←⍵⋄m÷∨/m←((r×j)+s×i),s×j}/1,¨⍳⍵}
  f 1
1 1 
  f 2
3 2 
  f 3
11 6 
  f 20
55835135 15519504 

몇 마디 말로 세트에서 "2 개의 분수 숫자의 합 함수"(1 개의 분수 숫자는 목록 2 정수)를 줄입니다.

1 2, 1 3,..., 1 n

아래는 잘못된 것 같습니다.

 f 56
74359641471727289 16124934538402170

그러나 입력 유형을 다음보다 변경하면 :

  f 56x
252476961434436524654789 54749786241679275146400 
  f 226x
31741146384418617995319820836410246588253008380307063166243468230254437801429301078323028997161 529022507845189
  3176693594241665890914638817631063334447389979640757204083936351078274058192000

1

APL (Dyalog Unicode) , 15 12 바이트

⌽!(,÷∨)1⊥!÷⍳

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

단일 인수를 취하는 암묵적 기능 . 분모를 먼저 인쇄하도록 허용 된 경우 를 제거하여 바이트를 저장합니다 .

3 바이트에 대해 @dzaima에게 감사드립니다.

어떻게:

⌽!(,÷∨)1⊥!÷⍳  Tacit function, argument will be called ⍵.
             Range 1..⍵ 
          ÷   Dividing
         !    the factorial of 
       1     Base-1 decode, aka sum;
 !(   )       Using that sum and the factorial of  as arguments, fork:
             (GCD
    ÷         dividing
   ,          the vector with both arguments)
             reversed.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.