Golf la sequenza la cui funzione generatrice esponenziale è tangente


15

Quasi ogni funzione può essere espressa come un polinomio con termini infiniti.

Per esempio, e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! + ...

Per esempio, sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...

I coefficienti dei ntermini -th formano una sequenza e la funzione corrispondente è chiamata Funzione generatrice della sequenza.

I coefficienti dei n-th termini formano una sequenza.

Spesso, l' nennesimo termine avrebbe un denominatore di n!. Pertanto, moltiplichiamo il coefficiente n!per ottenere un'altra sequenza, la cui funzione generatrice esponenziale sarebbe la funzione originale.

Ad esempio, la sequenza cui funzione esponenziale Generazione è e^xsarebbe 1,1,1,1,....

Ad esempio, la sequenza cui funzione esponenziale Generazione è sin(x)sarebbe 0,1,0,-1,0,1,0,-1,....

Compito

Il tuo compito è quello di trovare l' nennesimo termine della sequenza la cui funzione generatrice esponenziale è tan(x).

Casi test

n result
0 0
1 1
2 0
3 2
4 0
5 16
6 0
7 272
8 0
9 7936
10 0
11 353792
12 0
13 22368256
14 0
15 1903757312
16 0
17 209865342976
18 0
19 29088885112832
20 0
21 4951498053124096
22 0
23 1015423886506852352
24 0
25 246921480190207983616
26 0

(Copiato da qui .) (Attenzione: il 0termine è diverso)

Esempio di implementazione

# copied from https://github.com/Mego/Seriously/blob/v2.0/SeriouslyCommands.py#L16
def memoized(f):
    memo = {}
    def m_fun(*args):
        if args in memo:
            return memo[args]
        else:
            res = f(*args)
            memo[args] = res
            return res
    return m_fun

# copied from https://github.com/Mego/Seriously/blob/v2.0/SeriouslyCommands.py#L169
@memoized
def binomial(n,r):
    if r > n:
        return 0
    elif r==n:
        return 1
    res = 1
    i = 1
    while i<=r:
        res *= (n+1-i)
        res /= i
        i+=1
    return int(res)

# 2*u(n+1) = Sum_{k=0..n} binomial(n, k)*u(k)*u(n-k)
# from A000111
@memoized
def u(n):
    if n<0: return 0
    if n==0: return 1
    if n==1: return 1
    return sum([binomial(n-1,k)*u(k)*u(n-1-k) for k in range(n)])//2     

def t(n):
    if n%2 == 0: return 0
    return u(n)

print('\n'.join([str(x) + ' ' + str(t(x)) for x in range(26)]))

Ideone esso!

Riferimenti


4
Se vuoi saperne di più sulla generazione di funzioni e il loro uso in matematica, in particolare la teoria combinatoria e la teoria dei numeri, consiglio vivamente questa "famosa" funzionalità di generazione di libri di testo di H. Wilf.
Flawr,

5
(Non posso resistere): presa alla lettera, la tua prima frase è estremamente falsa!
Flounderer,

Hai il significato di "funzione generatrice" e di "funzione generatrice esponenziale" al contrario. $ \ sin (x) $ è la funzione generatrice esponenziale della sequenza 0,1,0, -1,0,1,0, -1,0, ... - non è la sequenza che è la funzione generatrice esponenziale di $ \ sin (x) $. Quello che ci stai chiedendo di fare è codificare la sequenza generata esponenzialmente da $ \ tan (x) $.
Glen O

Sembra a posto, tranne "Questa è anche chiamata la Funzione generatrice di quella funzione. I coefficienti degli ennesimi termini formano una sequenza", che probabilmente dovrebbe dire qualcosa come "I coefficienti degli ennesimi termini formano una sequenza, e la funzione corrispondente è chiamata la funzione generatrice della sequenza ".
Glen O

@GlenO Modificato.
Leaky Nun,

Risposte:


8

CJam ( 33 32 27 26 23 20 byte)

2,{ee::*_(@+.+}ri*0=

Demo online

Dissezione

Ciò implementa essenzialmente la ricorrenza descritta da xnor .

2,        e# [0 1] represents the base case f(0,j) = j==1
{         e# Loop...
  ee::*   e#   Multiply each array element by its index
  _(@+.+  e#   Sum the array shifted left and the array shifted right
}ri*      e# ... n times
0=        e# Evaluate at j=0

O con un approccio piuttosto diverso, per 23 byte:

ri_1&a{{1$+}*]W%0+}@*0=

Demo online . Grazie a Dennis per 3 byte.

Dissezione

1a         e# Push [1]
{          e# Repeat...
  {1$+}*]  e#   Compute array of partial sums
  W%0+     e#   Reverse and append 0
}qi:A*     e# ... A times, where A is the input value
0=A1&*     e# Result is first element if A odd, and 0 otherwise

O con un approccio molto diverso, per 29 byte:

qie!Ma-{W\+W+3ew{_$.=1=},!},,

Demo online

Purtroppo è necessario un caso speciale per l'input 0.

Dissezione

qi            e# Take an integer n from stdin
e!            e#   Compute all permutations of [0 ... n-1]
Ma-           e#   Special-case n=0
{             e#   Filter...
  W\+W+       e#     Prepend and postpend -1
  3ew         e#     Take slices of 3 consecutive elements
  {           e#     Filter...
    _$.=1=    e#       Test whether the middle element is the second largest
  },!         e#     ... and require no matches
},,           e#   ... and count

Potresti pensare "WTF ?! Sta rispondendo alla domanda sbagliata." In tal caso, è comprensibile, ma entrambi gli approcci danno effettivamente i risultati corretti .


Se ot aiuta, la build notturna su TIO restituisce un array vuoto per [WW]3ew.
Dennis,

@Dennis, grazie. Tuttavia, si scopre che 0deve essere comunque un caso speciale, perché valuta 1.
Peter Taylor,

1
Si potrebbe pensare che si sta rispondendo alla domanda sbagliata se non si è nemmeno fatto clic sui miei collegamenti.
Leaky Nun,

ri_1&a{{1$+}*]W%0+}@*0=salva 3 byte.
Dennis,

2
@LeakyNun, quindi sarebbero tutti allora. Ho visto quella lista di link e tl; dr.
Peter Taylor,

7

Julia, 40 38 32 byte

!n=2(2*4^n-2^n-0^n)abs(zeta(-n))

Ingresso e uscita sono in forma di BigFloats. Provalo online!

sfondo

La serie Maclaurin della funzione tangente soddisfa l'identità

ogni volta che x si trova nel suo raggio di convergenza, dove B n è un numero di Bernoulli.

Poiché B 2 (n + 1) e (-1) n hanno lo stesso segno, B 2n + 1 = 0 se n> 0 e B 1 = 1/2 , possiamo riscrivere quanto sopra come segue.

Inoltre, ogni volta che n è un numero intero non negativo, abbiamo

dove ζ indica la funzione zeta di Riemann .

Da ciò, con la convenzione 0 0 = 1 , ne consegue che

quale è la formula utilizzata dall'implementazione.


6

Python, 57 byte

f=lambda i,j=0:~-j*f(i-1,j-1)-~j*f(i-1,j+1)if i else j==1

Meno golf:

f=lambda i,j=0:j==1 if i==0 else (j-1)*f(i-1,j-1)+(j+1)*f(i-1,j+1)

Possiamo calcolare il icoefficiente th della funzione generatrice esponenziale differenziando i itempi della funzione tangente e valutando a 0. Ogni derivata è un polinomio in tan(x)e il suo valore a 0 è il suo termine costante.

Esprimiamo ricorsivamente il coefficiente di tan(x)**jnella iderivata th tancon la funzione f(i,j). L'espressione ricorsiva deriva dalla relazione tan(x)' = 1 + tan(x)**2.

Quindi, il derivato di tan(x)**jè

j*tan(x)**(j-1)*(tan(x)**2+1), or equivalently
j*tan(x)**(j+1) + j*tan(x)**(j-1)

Quindi, i contributori tan(x)**jnella iderivata th sono tan(x)**(j-1)e tan(x)**(j+1)nella (i-1)derivata st, ciascuno con un coefficiente uguale alla sua potenza. Questo dà l'espressione ricorsiva

f(i,j) = (j-1)*f(i-1,j-1) + (j+1)*f(i-1,j+1)

Nota che non è necessario escludere esponenti negativi jperché valutano comunque zero e non contribuiscono perché l'attraversamento j=0fornisce un moltiplicatore di 0.

Il caso base di i==0corrisponde a tan(x)se stesso con j==1e coefficienti zero altrimenti. La valutazione finale avviene a termine costante j=0, che viene inserito come valore predefinito.


Questo porta a 20 byte in CJam. Ti dispiace se faccio la mia risposta principale o vuoi portarla e pubblicarla?
Peter Taylor,

Dovresti pubblicarlo, non conosco CJam.
xnor

4

Mathematica, 20 byte

Tan@x~D~{x,#}/.x->0&

Approccio diretto. Calcolare il n ° derivata di tan (x) e valutare in x = 0 .

uso

Esempio


3

Haskell, 48 byte

0%1=1
0%_=0
i%j=sum[k*(i-1)%k|k<-[j+1,j-1]]
(%0)

Possiamo calcolare il icoefficiente th della funzione generatrice esponenziale differenziando i itempi della funzione tangente e valutando a 0. Ogni derivata è un polinomio in tan(x)e il valore a 0 è il suo termine costante.

Esprimiamo ricorsivamente il coefficiente di tan(x)^jnella iderivata th tancon la funzione i%j. L'espressione ricorsiva deriva dalla relazione tan(x)' = 1 + tan(x)^2.

Quindi, il derivato di tan(x)^jè

j*tan(x)^(j-1)*(tan(x)^2+1), or equivalently
j*tan(x)^(j+1) + j*tan(x)^(j-1)

Quindi, i contributori tan(x)^jnella iderivata th sono tan(x)^(j-1)e tan(x)^(j+1)nella (i-1)derivata st, ciascuno con un coefficiente uguale alla sua potenza.


3

Gelatina , 12 11 byte

Ṛ+\;S
ḂÇ⁸¡Ḣ

Come risposta CJam di Peter Taylor , questo calcola la n esimo termine di Eulero è up / down sequenza se n è dispari e speciali-casi anche n come 0 .

Provalo online! o verifica tutti i casi di test .

Come funziona

ḂÇ⁸¡Ḣ  Main link. Argument: n

Ḃ       Bit; yield n's parity.
 Ç⁸¡    Apply the helper link (Ç) n (⁸) times.
    Ḣ   Head; retrieve the first element of the resulting list.


Ṛ+\;S   Helper link. Argument: A (list or 1/0)

Ṛ       Cast A to list (if necessary) and reverse the result.
 +\     Take the cumulative sum.
   ;S   Append the sum of A.

3

Sage, 26 byte

lambda n:tan(x).diff(n)(0)

Come le altre soluzioni nei linguaggi orientati alla matematica, questa funzione calcola la nderivata ditan(x) e la valuta in x = 0.

Provalo online


2

J, 15 13 byte

C'è anche il comando incorporato t:che calcola il n esimo coefficiente della funzione generatrice esponenziale di tan (x) .

(1&o.%2&o.)t:

Grazie a @ Leaky Nun per avermi ricordato gli avverbi della serie Taylor in J che hanno salvato 2 byte.

Alternativa per 15 byte .

3 :'(3&o.d.y)0'

Un altro approccio è quello di calcolare la n esima derivata di tan (x) e valutare a x = 0 .

Nota: in J , la quantità di memoria utilizzata dalla funzione derivata d.aumenta rapidamente come n passa 10.

uso

   f =: (1&o.%2&o.)t:
   f 7
272
   (,.f"0) i. 11  NB. Additional commands are just for formatting the output
 0    0
 1    1
 2    0
 3    2
 4    0
 5   16
 6    0
 7  272
 8    0
 9 7936
10    0

Spiegazione

(1&o.%2&o.)t:  Input: n
(         )    Define a monad (one argument function), call the input y
 1&o.          Get the trig function sin(x) and call it on y
      2&o.     Get the trig function cos(x) and call it on y
     %         Divide sin(y) by cos(y) to get tan(y)
           t:  Get the nth coefficient of the exponential generating series
               for that function and return

3 :'(3&o.d.y)0'  Input: n
3 :'          '  Define a monad (one argument function) with input y
     3&o.        Get the trig function tan(x)
           y     The input n
         d.      Get the nth derivative of tan(x)
             0   Evaluate the nth derivative at x = 0 and return

2

Julia, 39 37 byte

!n=(spdiagm((0:n,1:n+1),(1,-1))^n)[2]

Salvato 2 byte grazie a Dennis.

Non la soluzione Julia più breve (vedi la soluzione di Dennis), ma questa è fatta semplicemente usando la logica derivata ... sotto forma di matrici.

Fondamentalmente, usa il fatto che la derivata di tan (x) è 1 + tan (x) ^ 2. Quindi, poiché la derivata di qualsiasi potere di abbronzatura (x), diciamo abbronzatura (x) ^ k, è k tan (x) ^ (k-1) tan (x) '= k tan (x) ^ (k-1) + k tan (x) ^ (k + 1), possiamo usare una semplice potenza di matrice su una matrice con i valori appropriati per generare l'espansione, con la seconda riga o colonna (a seconda della costruzione) che contiene le derivate di tan (x ) stesso.

Quindi dobbiamo solo trovare la costante nell'espressione risultante, e questo è il primo valore nella riga o colonna corrispondente.


!n=(spdiagm((0:n,1:n+1),(1,-1))^n)[2]dovrebbe funzionare.
Dennis,

@Dennis - bella cattura. Non avevo capito che spdiagmavrebbe permesso quello stile di costruzione - l'ho provato diagm, ma ovviamente non ha funzionato.
Glen O

2

JavaScript (ES6), 127 45 byte

f=(n,m=0)=>n?++m*f(--n,m--)+--m*f(n,m):m-1?0:1

Porta delle soluzioni di @ xnor.


0

Haskell, 95 93 byte

p=product
f n=sum[(-1)^(n`div`2+j+1)*j^n*p[k-j+1..n+1]`div`p[1..n+1-k+j]|k<-[1..n],j<-[0..k]]

È fondamentalmente un'implementazione della formula generale con alcune ottimizzazioni minori.


0

MATLAB con Symbolic Toolbox, 84 byte

n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)

Esempi di esecuzione:

>> n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)
7
ans =
272

>> n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)
8
ans =
0

>> n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)
9
ans =
7936

0

Haskell (troppi byte)

Utilizzando solo le operazioni sulle liste e il risultato di Raymond Manzoni :

c n = last $ map numerator $ zipWith (*) (scanl (*) (1) [2,3..]) (intersperse 0 $ foldr (.) id (replicate n (\xs->(xs ++ [(1%(1+2*length xs)) * (sum (zipWith (*) xs (reverse xs)))]))) [1])

Sfortunatamente, questo trabocca per valori modesti di n, in quanto utilizza Intvalori. Proverò a risolvere il problema usando i Integervalori. Fino ad allora, i suggerimenti sono benvenuti.


0

Assioma, 46 byte

f(n:NNI):NNI==(n=0=>0;eval(D(tan(x),x,n),x=0))

codice per test e risultati

(32) -> [[i, f(i)] for i in 0..26]
   (32)
   [[0,0], [1,1], [2,0], [3,2], [4,0], [5,16], [6,0], [7,272], [8,0], [9,7936],
    [10,0], [11,353792], [12,0], [13,22368256], [14,0], [15,1903757312],
    [16,0], [17,209865342976], [18,0], [19,29088885112832], [20,0],
    [21,4951498053124096], [22,0], [23,1015423886506852352], [24,0],
    [25,246921480190207983616], [26,0]]
                                       Type: List List NonNegativeInteger
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.