Denominatore di serie armoniche


16

In precedenza, abbiamo fatto lo pseudofattoriale di un numero, che è l'LCM dei numeri da 1a n.

Sarebbe utile aggiungere somme insieme.

Tuttavia, troviamo che il denominatore di 1/1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6è 20invece dello pseudofattoriale di 6, che è 60.

Il tuo compito è trovare il denominatore di 1/1 + 1/2 + ... + 1/nun intero positivo dato n.

Casi test

 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

Riferimenti

Classifica


Per quanto deve funzionare un input?
Brad Gilbert b2gills

@ BradGilbertb2gills Grande quanto ragionevole.
Leaky Nun,

Risposte:


8

M , 9 6 byte

Grazie a FryAmTheEggman per aver salvato 3 byte! Codice:

RİSg¹İ

M ha un enorme vantaggio qui, perché funziona con le frazioni anziché con i galleggianti. Spiegazione:

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)

Utilizza la codifica Jelly . Provalo online!.


Inoltre, esiste una soluzione a 4 byte , che a volte genera uno zero iniziale (ad es 280 -> 0280.). Non sono sicuro che ciò sia consentito o meno:

RİSV

Provalo online! .


1
1. La spiegazione del codice a 6 byte non è del tutto corretta. calcola il divisore comune più gratificato della frazione e n . L'uso g1sarebbe probabilmente più chiaro. 2. Vlancia la frazione in una stringa ed eva niladicamente. <num>/è (non cumulativo) ridotto da un operatore niladico. Questa è una sciocchezza, ma dato che esiste un solo numero (l'argomento implicito 0 ), semplicemente non fa nulla. Il collegamento successivo, il denominatore, è niladic, quindi il valore di ritorno precedente viene stampato implicitamente e sostituito con quel nilad.
Dennis,

@Dennis Grazie! Risolto il problema con la spiegazione.
Adnan,

@Adnan C'è qualche documentazione per M?
Esolanging Fruit,

@ Challenger5 Non che io sappia. In realtà è una variante di Jelly, ma con frazioni di precisione arbitrarie. La documentazione di Jelly può essere utilizzata, ma sii consapevole del fatto che molte funzionalità implementate in Jelly non sono implementate in M.
Adnan,

5

Julia, 22 byte

Una funzione anonima.

n->1.//(1:n)|>sum|>den

Stessa durata:n->sum(inv,1//1:n).den
Alex A.

4

Mathematica, 27 byte

Una funzione anonima.

Denominator@*HarmonicNumber

Per esempio:

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

Potresti trovare una soluzione a 26 byte se scavi in ​​chat :)
Leaky Nun,

Oh! Dovrei lasciare che Martin lo pubblichi, se gli piace. Questo è adorabile letteralmente, quindi lo terrò.
Lynn,

Vuoi esemplificare come viene utilizzato il codice?
DavidC,

3

Python 2, 69 67 byte

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

Provalo su Ideone .

Come funziona

Sia H (n) la somma degli inversi moltiplicativi dei primi n numeri interi positivi. In ogni momento, abbiamo che a / b = 1 + H (k - 1) . In effetti, a , b e k sono tutti inizializzati su 1 e 1/1 = 1 = 1 + H (0) .

Ripetiamo lo snippet di codice

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

(come stringa) n (input) volte ed esegue il risultato. In ogni passaggio, aggiorniamo a , b e k usando l'identità a / b + 1 / k = ak / bk + b / bk = (ak + b) / bk .

Dopo che tutte le copie sono state eseguite, a / b = 1 + H (n) , che ha lo stesso denominatore di H (n) .

La forma completamente ridotta di a / b è (a ÷ gcd (a, b)) / (b ÷ gcd (a, b)) . Invece di calcolare il massimo comune divisore, inizializziamo r come 1 e continuiamo ad aumentare r fino a quando ra è un multiplo di b .

Chiaramente, questo rende RA il minimo comune multiplo di un e b . Poiché gcd (a, b) · mcm (a, b) = ab , abbiamo che b ÷ gcd (a, b) = mcm (a, b) ÷ a = ra ÷ a = r , rendendo r l'output desiderato.


3

Haskell, 52

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

Se il file viene caricato in GHCI, f può essere utilizzato come funzione.


1
Presumibilmente vuoi dire importminuscole? Salva un byte per usare un mapinvece di una comprensione:sum$map(1%)[1..n]
xnor

2

Gelatina, 9 byte

!©÷RSg®®÷

Provalo qui.

             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.

Credo che sia possibile ottenere lo stesso bytecount senza quel registro.
Leaky Nun,

2

MATL , 14 13 byte

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

Provalo online!

Spiegazione

Per l'ingresso N , l'uscita è limitata da N ! (fattoriale di N ). Il codice calcola n / k per n = 1, ..., N ! e per k = 1, ..., N . Quindi somma su k , che dà il numero armonico moltiplicato per ogni n . Il risultato desiderato è l'indice n del primo di quei valori che è un numero intero.


2

Rubino, 57 47 byte

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

Grazie a Kevin Lau per averlo abbreviato di dieci byte.


Assegna una variabile a in 1.to_rmodo da non dover eseguire l'iniezione e la conversione di stringhe. Inoltre, poiché l'impostazione predefinita di Ruby reduceè l'uso del primo elemento come iniziale e 1/1=1non è necessario impostare specificamente 0come valore iniziale.
Value Ink

2

Mathematica, 26 byte

Denominator@Tr[1/Range@#]&

Una funzione senza nome che accetta ncome input e restituisce il denominatore. Utilizza il trucco standard di abuso Tr(traccia) per sommare l'elenco dei reciproci.


1

JavaScript (ES6), 88 byte

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}

Funziona solo fino a m = 20 a causa dei limiti della precisione numerica di JavaScript.


1

05AB1E , 8 byte

Codice:

!йL/O¿/

Spiegazione:

!         # 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.

Potrebbero esserci alcuni problemi di precisione per n> 19 a causa della divisione di Python ... Utilizza la codifica CP-1252 .

Provalo online! .



0

J, 20 byte

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

Basato sull'approccio utilizzato dalla soluzione di @ Lynn .

Se la precisione non è necessaria per valori elevati di n o se possiamo supporre che n verrà passato come numero intero esteso, suffisso da x, è possibile utilizzare una soluzione più breve per 15 byte .

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

uso

   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

Spiegazione

(!%!+.[:+/!%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 byte

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

Spiegazione:

{
  (
    [+]        # 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
}

Test:

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

Hoon , 95 byte

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

Crea un elenco [1...n], piegalo con ++mulil fattoriale, crea un elenco [n!/1, n!/2, ... n!/n]e sommalo, trova GCD din! e l'elenco e dividi il fattoriale per quel numero.

C'è probabilmente un modo molto più semplice per calcolare il denominatore, ma non riesco a capirlo: /


Oh Hoon, perché il tuo tokenizer ha bisogno di così tanti spazi bianchi ridondanti?
Leaky Nun,

Tutte le mie voci Hoon sembrano brutte a causa delle nuove righe :( Il codice Hoon normale utilizza due spazi tra i token, ma una nuova riga è più breve
RenderSettings

0

Python 3, 153 150 146 142 byte

Sono sicuro che questo può giocare a golf ulteriormente. Ma sono nuovo qui

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

Benvenuti in PPCG!
Leaky Nun,

0

Assioma, 34 byte

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

test

(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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.