Знаменник гармонійних рядів


16

Раніше ми робили псевдофакторну кількість, яка є LCM чисел від 1до n.

Було б корисно поєднувати дроби разом.

Однак ми виявляємо, що знаменник « 1/1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6є» 20замість псевдофакторного 6, який є 60.

Ваше завдання - знайти знаменник 1/1 + 1/2 + ... + 1/nзаданого натурального числа n.

Тестові шафи

 n result
 1 1
 2 2
 3 6
 4 12
 5 60
 6 20
 7 140
 8 280
 9 2520
10 2520
11 27720
12 27720
13 360360
14 360360
15 360360
16 720720
17 12252240
18 4084080
19 77597520
20 15519504
21 5173168
22 5173168
23 118982864
24 356948592
25 8923714800
26 8923714800
27 80313433200
28 80313433200
29 2329089562800
30 2329089562800

Список літератури

Таблиця лідерів


Наскільки великий вхід повинен працювати?
Бред Гілберт b2gills

@ BradGilbertb2gills Наскільки великий розум.
Лина монашка

Відповіді:


8

М , 9 6 байт

Завдяки FryAmTheEggman за збереження 3 байтів! Код:

RİSg¹İ

M має тут величезну перевагу, оскільки він працює з дробами, а не плаває. Пояснення:

R       # Get the list [1 ... n].
 İ      # Inverse each, resulting into [1/1, 1/2, 1/3, ..., 1/n].
  S     # Sum it up. (86021/27720 for n=12)
   g¹   # Compute the greatest common denominator with n. (1/27720 for n=12)
     İ  # Calculate the inverse again. (27720 for n=12)

Використовує кодування Jelly . Спробуйте в Інтернеті!.


Також існує 4-байтне рішення, яке іноді видає провідний нуль (наприклад 280 -> 0280). Я не впевнений, дозволено це чи ні:

RİSV

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


1
1. Пояснення 6-байтового коду не зовсім коректно. обчислює найбільший спільний дільник дробу і n . g1Можливо, використання було б зрозумілішим. 2. Vвідкидає дріб до струни та евакуює її ніладично. <num>/є (некумулятивним) зменшенням від ніладичного оператора. Це нісенітниця, але оскільки є лише одне число (неявний аргумент 0 ), воно просто нічого не робить. Наступне посилання, знаменник, є niladic, тому попереднє повернене значення друкується неявно і замінюється цим nilad.
Денніс

@Dennis Дякую! Виправлено пояснення.
Аднан

@Adnan Чи є документація на M?
Esolanging Fruit

@ Challenger5 Не те, що я знаю. Це насправді варіант желе, але з довільною точністю фракцій. Документацію Jelly можна використовувати, але слід очікувати, що багато можливостей, реалізованих у Jelly, не реалізовані в М.
Аднан


4

Математика, 27 байт

Анонімна функція.

Denominator@*HarmonicNumber

Наприклад:

 In[1] := (Denominator@*HarmonicNumber)[10]
 Out[1] = 2520

Ви можете знайти 26-байтне рішення, якщо зануритися в чат :)
Leaky Nun

Ой! Я повинен дозволити Мартіну опублікувати цю, якщо йому подобається. Цей чарівний буквально, тому я його буду тримати.
Лінн

Ви б пояснили, як використовується код?
DavidC

3

Python 2, 69 67 байт

a=b=k=r=1
exec'a=a*k+b;b*=k;k+=1;'*input()
while r*a%b:r+=1
print r

Перевірте це на Ideone .

Як це працює

Нехай H (n) - сума мультиплікативних обернень перших n натуральних чисел. У всі часи маємо, що a / b = 1 + H (k - 1) . Насправді, a , b і k всі ініціалізовані на 1 , а 1/1 = 1 = 1 + H (0) .

Повторюємо фрагмент коду

a=a*k+b;b*=k;k+=1;

(як рядок) n (вхідний) раз і виконати результат. На кожному кроці ми оновлюємо a , b і k, використовуючи тотожність a / b + 1 / k = ak / bk + b / bk = (ak + b) / bk .

Після того, як всі копії виконані, a / b = 1 + H (n) , який має той же знаменник, що і H (n) .

Повністю скорочена форма a / b є (a ÷ gcd (a, b)) / (b ÷ gcd (a, b)) . Замість обчислення найбільшого спільного дільника ми ініціалізуємо r як 1 і продовжуємо збільшувати r, поки ra не кратно b .

Зрозуміло, це робить ra найменш поширеним кратним a і b . Оскільки gcd (a, b) · lcm (a, b) = ab , маємо, що b ÷ gcd (a, b) = lcm (a, b) ÷ a = ra ÷ a = r , роблячи r бажаним результатом.


3

Хаскелл, 52 роки

Import Data.Ratio
f n=denominator$sum[1%k|k<-[1..n]]

Якщо файл завантажується в GHCI, f може бути використаний як функція.


1
Ви, мабуть, маєте на увазі importмалі літери? Це економить байт, щоб використовувати mapзамість розуміння:sum$map(1%)[1..n]
xnor

2

Желе, 9 байт

!©÷RSg®®÷

Спробуйте тут.

             Argument: n
! ÷R         Compute [n!÷1, n!÷2, … n!÷n].
 ©             (And store n! in the register.)
    S        Find the sum of this list.
     g®      GCD with n!.
       ®÷    Divide n! by this GCD.

Я вважаю, що можна досягти одного і того ж обліку без цього реєстру.
Лина монашка

2

MATL , 14 13 байт

:p:G:!/s1\&X<

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

Пояснення

Для входу N вихід має верхню межу N ! (факторіал N ). Код обчислює n / k для n = 1, ..., N ! і до = 1, ..., N . Тоді вона підсумовує k , що дає гармонічне число, помножене на кожне n . Бажаним результатом є індекс n першого з тих значень, який є цілим числом.


2

Рубі, 57 47 байт

->n{(1..n).reduce{|a,i|a+1.to_r/i}.denominator}

Дякую Кевіну Лау за скорочення цього на десять байтів.


Призначте змінну 1.to_rтак, що вам не потрібно робити рядок введення та перетворення. Крім того, оскільки Рубі за замовчуванням для reduce- це використовувати перший елемент як вихідний, і 1/1=1вам не потрібно спеціально встановлювати 0як початкове значення.
Значення чорнила

2

Математика, 26 байт

Denominator@Tr[1/Range@#]&

Безіменна функція, яка бере nвхід і повертає знаменник. Використовує стандартний трюк зловживання Tr(сліду) для підсумовування списку взаємних звернень.


1

JavaScript (ES6), 88 байт

m=>{for(d=1,i=0;i<m;d*=++i);for(n=i=0;i<m;n+=d/++i);for(g=d;g;[g,n]=[n%g,g]);return d/n}

Працює до m = 20 через межі числової точності JavaScript.


1

05AB1E , 8 байт

Код:

!йL/O¿/

Пояснення:

!         # Take the factorial of the input.
 Ð        # Triplicate this.
  ¹L      # Get the list [1 ... input].
    /O    # Divide and sum up.
      ¿   # Get the GCD of the sum and the factorial.
       /  # Divide the factorial by this.

Можуть виникнути проблеми з точністю для n> 19 через поділ Python ... Використовує кодування CP-1252 .

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



0

J, 20 байт

(!%!+.[:+/!%1+i.)@x:

На основі підходу , використовуваного @ Лінн рішення .

Якщо точність не потрібна для великих значень n, або якщо ми можемо припустити, що n буде передано як розширене ціле число, суфікс x, може бути використаний коротший розчин на 15 байт .

!%!+.[:+/!%1+i.

Використання

   f =: (!%!+.[:+/!%1+i.)@x:
   f 30
2329089562800
   (,:f"0) >: i. 15
1 2 3  4  5  6   7   8    9   10    11    12     13     14     15
1 2 6 12 60 20 140 280 2520 2520 27720 27720 360360 360360 360360

Пояснення

(!%!+.[:+/!%1+i.)@x:  Input: n
                  x:  Convert n into an extended integer
              i.      Creates the range [0, 1, ..., n-1]
            1+        Add one to each, range is now [1, 2, ..., n]
          !           Get factorial of n
           %          Divide n! by each value in the range [1, 2, ..., n]
      [:+/            Sum those values
   !                  Get n!
    +.                Get gcd between n! and the sum
 !                    Get n!
  %                   Divide n! by the gcd and return

0

Perl 6 ,  36  32 байти

{([+] 1.FatRat X/1..$_).denominator}
{([+] 1.FatRat X/1..$_).nude[1]}

Пояснення:

{
  (
    [+]        # reduce with &infix:<+>

      # the following produces a Seq of Rational numbers
      # 1/1, 1/2, 1/3 ... 1/n

      1.FatRat # FatRat.new: 1,1
      X/       # crossed using &infix:</>
      1 .. $_  # Range from 1 to the input inclusive

  ) # resulting in a FatRat

  .nude # (nu)merator (de)nominator
  .[1]  # grab the denominator
}

Тест:

my &hd = {([+] 1.FatRat X/1..$_).nude[1]}

say (1..10)».&hd; # (1 2 6 12 60 20 140 280 2520 2520)

say hd 100; # 2788815009188499086581352357412492142272
say chars hd 1000; # 433
say chars hd 10000; # 4345

0

Хун , 95 байт

|=
@
=+
n=(gulf 1 +<)
=+
f=(roll n mul)
(div f d:(egcd f (roll (turn n |=(@ (div f +<))) add)))

Створіть список [1...n], складіть його ++mulза допомогою факторіалу, створіть список [n!/1, n!/2, ... n!/n]і підсумовуйте його, знайдіть GCD n!та список і поділіть факторіал на це число.

Напевно, існує набагато простіший спосіб обчислити знаменник, але я не можу це зрозуміти: /


О, Хун, чому твоєму токенізатору потрібно стільки зайвих пробілів?
Leaky Nun

Усі мої записи Hoon виглядають некрасиво через нові рядки :( Нормальний код Hoon використовує два пробіли між маркерами, але один новий рядок коротший
RenderSettings

0

Python 3, 153 150 146 142 байт

Я впевнений, що це може продовжити гольф далі. Але я тут новий

f=lambda x:0**x or x*f(x-1)
z=int(input());i=f(z)
r=sum(i/y for y in range(1,z+1))  
p=lambda a,b:a if b<1else not a%b+b or p(b,a%b)
print(i/p(r,i))

Ласкаво просимо до PPCG!
Лина монашка

0

Аксіома, 34 байти

f(x)==denominator(sum(1/n,n=1..x))

тест

(24) -> [[i,f(i)] for i in 1..30]
   (24)
   [[1,1], [2,2], [3,6], [4,12], [5,60], [6,20], [7,140], [8,280], [9,2520],
    [10,2520], [11,27720], [12,27720], [13,360360], [14,360360], [15,360360],
    [16,720720], [17,12252240], [18,4084080], [19,77597520], [20,15519504],
    [21,5173168], [22,5173168], [23,118982864], [24,356948592],
    [25,8923714800], [26,8923714800], [27,80313433200], [28,80313433200],
    [29,2329089562800], [30,2329089562800]]
                                       Type: List List Expression Integer

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.