Harmonik Serilerin Tam Kısmi Toplamı


15

Meydan okuma

Pozitif bir tamsayı verildiğinde N, ilk Nkarşılıklıların toplamını kesin bir kesir olarak çıktılar; bu, pay ve paydayı temsil eden tutarlı bir sırayla bir tam sayı çifti olarak temsil edilir.

kurallar

  • Çıktı kesin olmalıdır.

  • Çıktı, pay ve paydayı temsil eden tutarlı bir sırayla bir çift tam sayı olmalıdır.

  • Tamsayı olmayan sayısal türlerin (yerleşik veya kütüphane) kullanılması yasaktır.

    • Açıklama / istisna: tamsayı olmayan sayısal türler, yalnızca kullanılan, hesaplanan ve döndürülen tüm değerler tamsayı ise (yani, diliniz varsayılan olarak rasyonel sayılar kullanır, ancak yanıtınızda yalnızca tamsayı aritmetiği kullanırsanız) uygundur.
  • Çıktı mümkün olduğunca azaltılmalıdır. ( 3/2tamam, 6/4değil)

  • Standart boşluklar yasaktır.

  • Sunumlar , hangisi daha yüksekse en az 20'ye kadar olan girdiler veya bu meta için çalışmalıdır .

Test Durumları

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

Test Kutusu Üretimi (Python 3)

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

Bu meydan okumaya ve bu meydan okumaya benzer .

Numerators olan OEIS A001008 ve paydası olan OEIS A002805 .




Diliniz bunu sağlıyorsa gcd"yerleşik bir işlev" midir?
Chas Brown

@ChasBrown gcdve diğer yerleşik işlevler gayet iyi. Rasyonel / kesirli türlere izin verilmez.
pizzalar184

1
@JoKing Yalnızca tamsayılar kullanıldığı sürece sayılar rasyonel tipteyse sorun olmaz. Soruyu güncelleyeceğim.
pizzapants184

Yanıtlar:


8

Python 2 , 80 79 bayt

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

Çevrimiçi deneyin!

Pay ve payda yazdırır.

Yaşasın! MathJax desteği !!!! Biri gözlemler:

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

Sonra, pozitif için, umenterde özyineleme hakkında düşünmek:nN

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

ve Denominator n'i düşünmeye yardım edemez !n!özyinelemeli olarak; böylece exec.

Redükte Kesir Piper'ı whiledöngüde bir GCD hesaplaması ile ödemeliyiz ; ve sonra işimiz bitti.


7

Jöle , 10 bayt

!:RS,!:g/$

Çevrimiçi deneyin!

Nasıl çalışır

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

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

Çevrimiçi deneyin!

Örnekleri çalıştır

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

Nasıl çalışır

!(,%+.)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 bayt, kesir türü kullanarak

1#.1%1+i.

Çevrimiçi deneyin!

J bölünemez değilse int-int bölümü için kesirler verir.




Misiniz 2 x:1#.1%1+i.geçerli bir cevap olarak saymak veya bu rasyonel türde bir geçersiz yarar?
cole

5

05AB1E , 10 bayt

!DIL÷O)D¿÷

Çevrimiçi deneyin!

Diğer tüm girişlerle aynı yöntemi kullanır. Çıktı formunda [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 bayt

İade [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]

Çevrimiçi deneyin!

Nasıl?

Yöntem @ ChasBrown'un Python cevabına benzer .

birbbir=0b=1

birbirn+bbbnnn-1

n=0

(bir,b)(p,q)birgcd(bir,b)

birbbbirşıkb

b=0

p/birq/bir


3

Perl 6 , 57 53 bayt

{+($!=[*] 1..$_)/($!=($/=sum $! X/1..$_)gcd$!),$//$!}

Çevrimiçi deneyin!

Bir tamsayı alan ve bir demet döndüren anonim bir kod bloğu denominator, numerator.

Kesirli türleri kullanmamıza izin verilirse, çok daha basit 32 byter olurdu:

{sum(map 1/*.FatRat,1..$_).nude}

Çevrimiçi deneyin!



2

C ++ 17 (gcc) , 108 bayt

Yalnızca tamsayı aritmetiği kullanın:

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

Çevrimiçi deneyin!


C ++ 17 (gcc) , 108 bayt

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

Çevrimiçi deneyin!

Aşağıdaki ile aynı, ancak C ++ 17 kullanın std::gcd.


C ++ (gcc) , 109 bayt

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

Çevrimiçi deneyin!

C ++ yerel bigint desteğine sahip olmadığından, bu kesinlikle n>20 .

gerektir:

  • gcc'nin kullanımdan kaldırılmış importifadesi.
  • gcc's std::__gcd.
  • -O0(Sanırım) aksi takdirde derleyici optimize eder d/=a.
  • En az 64 bit long.

Açıklama:

  • İzin Vermek d=n!,bir='Hn.
  • Yuvarlak a*dyakın döküm yoluyla tam sayıya a*d+.5kadar longkadar ve assign n. Şimdi n/dçıktı.
  • Kesiri ile basitleştirin std::__gcd.

(1 karakter daha az) auto a=0.yerine kullanamaz double a=0mısınız?
Dan M.

Evet yapabilir. Ve döngüden bir bayt daha: 106 bayt
movatica


2

MATL, 13 bayt

:tptb/sht&Zd/

MATL Online'da deneyin

@Dennis 'Jelly cevabında kullanılanla aynı yöntem .

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

(Örtük çıktı, önce paydayı sonra da pay yazdırır.)

Kayan nokta yanlışlıkları, n = 20 için işe yaramadığı anlamına gelir, çünkü ara değerler çok büyüktür.Test senaryosu çıktısının bir yazım hatası olduğu anlaşılıyor, bu n = 20 için olan diğer cevaplarla aynı cevabı döndürüyor.

İşte bu arada bulmadan önce denedim bir tamsayı türü koruma sürümü (25 bayt):

25 bayt, giriş 43'e kadar

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

Çevrimiçi deneyin!

Numaralar atmalarını uint64(kullanmadan onlara ameliyat açıkça bir döngü içinde aritmetik yapmadan önce prodveya sum). Daha da önemlisi, kısmi sayıları ve paydaları, her bir yinelemenin sonunda, yol boyunca her adımda GCD'lerine böler. Bu, giriş aralığını n43'e kadar izin verecek şekilde artırır. Kodun bir kısmı @Chas Brown'un Python cevabına dayanır.

Faktöriyel yerine LCM kullanan alternatif (orijinal) yöntem:

16 15 bayt

:t&Zmtb/sht&Zd/

MATL Online'da deneyin


1

Excel VBA, 141 bayt

[A1]Konsoldan girdi alır ve konsola çıktı verir.

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 ve Yorumladı

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

dc , 87 bayt

?sn1dsNsD[lndlDdlNln*+sN*sD1-dsn1<M]sMln1<MlDsAlNsB[lAlB%sTlBsAlTsBlB0<G]dsGxlDlA/lNlA/

Çevrimiçi deneyin!

Bu, pay ve paydayı bu çıkış varsayılanının izin verdiği şekilde yığının üstüne bırakır . Yana dcolmayan bir gcdyerleşik, bu kullanan Öklit algoritması hesaplamak için gcd.


1

Stax , 11 bayt

ó╢Δ'åç4}ú┌7

Çalıştır ve hata ayıkla

Açıklama:

Hesaplamak istiyoruz:

Σben=1n1ben

Şimdi bir paydaya ihtiyacımız var b ve payların bir listesi birben:

Σben=1nbirbenb=Σben=1nbirbenb

Yapabiliriz b=n!, o zaman elimizde:

birbenn!=1ben|xn!birben=n!ben

Böylece sahibiz:

Σben=1n1n=Σben=1nn!benn!
|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 karakter, 112 bayt

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

Ölçek:

  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 

Birkaç kelimeyle, kümedeki "2 kesir sayısında toplam işlevi" (bir kesir sayısı bir liste 2 tamsayıları) azaltır:

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

aşağıdaki yanlış görünüyor:

 f 56
74359641471727289 16124934538402170

ama ben girdi türünü değiştirmek daha:

  f 56x
252476961434436524654789 54749786241679275146400 
  f 226x
31741146384418617995319820836410246588253008380307063166243468230254437801429301078323028997161 529022507845189
  3176693594241665890914638817631063334447389979640757204083936351078274058192000

1

APL (Dyalog Unicode) , 15 12 bayt

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

Çevrimiçi deneyin!

Tacit işlevi, tek bir argüman alarak . İlk önce paydayı yazdırmamıza izin veriliyorsa , bir bayt kaydeder .

3 byte için @ dzaima teşekkürler.

Nasıl:

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