Точна часткова сума гармонійних рядів


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

Python 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!

Тоді, думаючи про рекурсію, для n позитивних, у Nсемінарі:

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

і не можна не думати про Dзнавцятакож рекурсивно; таким чином.n!exec

Ми повинні заплатити трубопроводу з зменшеною фракцією з розрахунком GCD в whileциклі; і тоді ми закінчили.



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

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]

Спробуйте в Інтернеті!

Як?

Метод схожий на відповідь Python @ ChasBrown .

Спочатку обчислюємо незменшений чисельник аба=0б=1

аан+бббннн-1

н=0

(а,б)(p,q)аgcd(а,б)

аббамодб

б=0

p/аq/а


3

Perl 6 , 57 53 байти

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

Спробуйте в Інтернеті!

Блок анонімного коду, який приймає ціле число і повертає кортеж denominator, numerator.

Якби нам дозволяли використовувати дробові типи, це було б набагато простішим 32 байтом:

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

Спробуйте в Інтернеті!



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 .

Потрібно:

  • застаріле importтвердження gcc .
  • gcc's std::__gcd.
  • -O0(Я думаю, що так) інакше компілятор оптимізує d/=a.
  • Принаймні 64-розрядні long.

Пояснення:

  • г=н!,а=Нн
  • Обведіть a*dдо найближчого цілого числа, перейшовши a*d+.5на longта призначте n. Зараз n/d- вихід.
  • Спростіть дріб за допомогою std::__gcd.

Ви не можете використовувати auto a=0.замість double a=0(на 1 сім менше)?
Дан М.

Так він може. І ще один байт з циклу: 106 байт
movatica


2

MATL, 13 байт

:tptb/sht&Zd/

Спробуйте це на MATL Online

Той самий метод, який застосовується у відповіді на желе @Dennis .

: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. Частина коду заснована на відповіді Python @Chas Брауна.

Альтернативний (оригінальний) метод, використовуючи 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

постійного струму , 87 байт

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

Спробуйте в Інтернеті!

Це залишає чисельник і знаменник на вершині стека в тому порядку, як це дозволено цим вихідним типом. Оскільки dcвін не має gcdвбудованого, це використовує алгоритм Евкліда для обчислення gcd.


1

Стакс , 11 байт

ó╢Δ'åç4}ú┌7

Запустіть і налагоджуйте його

Пояснення:

Ми хочемо розрахувати:

i=1н1i

Зараз нам потрібен знаменник б і список чисельників аi:

i=1наiб=i=1наiб

Ми можемо зробити б=н!, то у нас є:

аiн!=1i|×н!аi=н!i

Отже, у нас є:

i=1н1н=i=1нн!iн!
|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 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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.