調和級数の正確な部分和


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「組み込み関数」あなたの言語がそれを提供している場合?
チャスブラウン

@ChasBrown gcdおよびその他の組み込み関数は問題ありません。有理/分数型は許可されていません。
pizzapants184

1
@JoKing整数のみが使用されている限り、数値が有理型であれば問題ありません。質問を更新します。
pizzapants184

回答:


8

パイソン280の 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!

次に、分子のに対して、再帰について考えます。nN

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

そして、人はD分母を考えずにはいられません再帰的にも。したがって。nexec

whileループ内でGCD計算を使用して、Reduced Fraction Piperに支払う必要があります。これで完了です。



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.有効な回答としてカウント、またはこれは、合理的なタイプの無効な使用ですか?
コール

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

JavaScript(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)

abbaモッドb

b=0

最終的に、縮小された分子返します。p/aq/a




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のstd::__gcd
  • -O0 (そうだと思います)そうでない場合、コンパイラは最適化されます d/=aます。
  • 少なくとも64ビットlong

説明:

  • させる d=na=Hn
  • a*dキャストa*d+.5して最も近い整数に丸めlong、に割り当てnます。これn/dが出力です。
  • で分数を単純化しstd::__gcdます。

(1文字少ない)のauto a=0.代わりに使用することはできませんdouble a=0か?
ダンM.

はい、彼は出来ます。ループからもう1バイト: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)

非ゴルフとコメント

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

実行してデバッグする

説明:

計算したい:

=1n1

今、分母が必要です b および分子のリスト a

=1nab==1nab

私たちは作れる b=n、それから:

an=1|×na=n

だから私たちは持っています:

=1n1n==1nnn
|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⊥!÷⍳

オンラインでお試しください!

単一の引数を取る暗黙の関数。を削除してバイトを保存します最初に分母を印刷できる場合は。

@dzaimaに3バイトありがとう。

どうやって:

⌽!(,÷∨)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.