Golf la séquence dont la fonction de génération exponentielle est tangente


15

Presque toutes les fonctions peuvent être exprimées comme un polynôme avec des termes infinis.

Par exemple, e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! + ...

Par exemple, sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...

Les coefficients des ntermes -th forment une séquence, et la fonction correspondante est appelée la fonction génératrice de la séquence.

Les coefficients des n-èmes termes forment une séquence.

Souvent, le n-ème terme aurait un dénominateur de n!. Par conséquent, nous multiplions le coefficient par n!pour obtenir une autre séquence, dont la fonction de génération exponentielle serait la fonction d'origine.

Par exemple, la séquence dont la fonction de génération exponentielle est e^xserait 1,1,1,1,....

Par exemple, la séquence dont la fonction de génération exponentielle est sin(x)serait 0,1,0,-1,0,1,0,-1,....

Tâche

Votre tâche consiste à trouver le n-ème terme de la séquence dont la fonction de génération exponentielle est tan(x).

Cas de 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

(Copié d' ici .) (Attention: le 0-ème terme est différent)

Exemple d'implémentation

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

Les références


4
Si vous voulez en savoir plus sur la génération de fonctions et leur utilisation en mathématiques, en particulier la combinatoire et la théorie numérique, je recommande fortement ce manuel de génération de manuels "célèbre" par H. Wilf.
flawr

5
(Impossible de résister): prise à la lettre, votre première phrase est extrêmement fausse!
Flounderer

Vous avez votre sens de «fonction de génération» et de «fonction de génération exponentielle» à l'envers. $ \ sin (x) $ est la fonction de génération exponentielle de la séquence 0,1,0, -1,0,1,0, -1,0, ... - ce n'est pas la séquence qui est la fonction de génération exponentielle de $ \ sin (x) $. Ce que vous nous demandez, c'est de coder la séquence générée exponentiellement par $ \ tan (x) $.
Glen O

Cela semble bien, sauf "Ceci est aussi appelé la fonction génératrice de cette fonction. Les coefficients des n-èmes termes forment une séquence.", Qui devrait probablement dire quelque chose comme "Les coefficients des n-èmes termes forment une séquence, et la fonction correspondante est appelée fonction génératrice de la séquence ".
Glen O

@GlenO Edited.
Leaky Nun

Réponses:


8

CJam ( 33 32 27 26 23 20 octets)

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

Démo en ligne

Dissection

Cela implémente essentiellement la récurrence décrite par 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

Ou avec une approche assez différente, pour 23 octets:

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

Démo en ligne . Merci à Dennis pour 3 octets.

Dissection

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

Ou avec une approche très différente, pour 29 octets:

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

Démo en ligne

Malheureusement, un cas spécial est requis pour la saisie 0.

Dissection

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

Vous pensez peut-être "WTF?! Il répond à la mauvaise question." Si c'est le cas, c'est compréhensible, mais les deux approches donnent effectivement les bons résultats .


Si ot aide, la compilation nocturne sur TIO renvoie un tableau vide pour [WW]3ew.
Dennis

@Dennis, merci. Cependant, il s'avère que cela 0doit être un cas spécial de toute façon, car il est évalué 1.
Peter Taylor

1
On ne penserait que vous répondez à la mauvaise question que si vous n'avez même pas cliqué sur mes liens.
Leaky Nun

ri_1&a{{1$+}*]W%0+}@*0=enregistre 3 octets.
Dennis

2
@LeakyNun, ce serait donc tout le monde alors. J'ai vu cette liste de liens et tl; dr.
Peter Taylor

7

Julia, 40 38 32 octets

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

L'entrée et la sortie prennent la forme de l' BigFloatart. Essayez-le en ligne!

Contexte

La série Maclaurin de la fonction tangente satisfait l'identité

chaque fois que x se trouve dans son rayon de convergence, où B n est un nombre de Bernoulli.

Puisque B 2 (n + 1) et (-1) n ont le même signe, B 2n + 1 = 0 si n> 0 et B 1 = 1/2 , nous pouvons réécrire ce qui précède comme suit.

De plus, chaque fois que n est un entier non négatif, nous avons

ζ désigne la fonction zêta de Riemann .

De cela, avec la convention 0 0 = 1 , il s'ensuit que

qui est la formule utilisée par l'implémentation.


6

Python, 57 octets

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

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

Nous pouvons calculer le ie coefficient de la fonction de génération exponentielle en différenciant les itemps de fonction tangente et en évaluant à 0. Chaque dérivée est un polynôme tan(x)et sa valeur à 0 est son terme constant.

Nous exprimons récursivement le coefficient de tan(x)**jdans la idérivée e de tanavec la fonction f(i,j). L'expression récursive vient de la relation tan(x)' = 1 + tan(x)**2.

Ainsi, la dérivée de tan(x)**jest

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

Ainsi, les contributeurs à tan(x)**jla idérivée e sont tan(x)**(j-1)et tan(x)**(j+1)à la (i-1)dérivée st, chacun avec un coefficient égal à sa puissance. Cela donne l'expression récursive

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

Notez que nous n'avons pas besoin d'exclure les exposants négatifs jcar ils évaluent à zéro de toute façon et ne contribuent pas car le croisement j=0donne un multiplicateur de 0.

Le cas de base de i==0correspond à tan(x)lui-même avec j==1, et zéro coefficients sinon. L'évaluation finale a lieu à terme constant j=0, qui est inséré comme valeur par défaut.


Cela porte à 20 octets dans CJam. Cela vous dérange-t-il si j'en fais ma réponse principale, ou voulez-vous le porter et le publier?
Peter Taylor

Vous devriez le poster, je ne connais pas CJam.
xnor

4

Mathematica, 20 octets

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

Approche directe. Calculez la n ème dérivée de tan (x) et évaluez-la à x = 0 .

Usage

Exemple


3

Haskell, 48 octets

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

Nous pouvons calculer le ie coefficient de la fonction de génération exponentielle en différenciant les itemps de fonction tangente et en évaluant à 0. Chaque dérivée est un polynômetan(x) et la valeur à 0 est son terme constant.

Nous exprimons récursivement le coefficient de tan(x)^jdans la idérivée e de tanavec la fonction i%j. L'expression récursive vient de la relationtan(x)' = 1 + tan(x)^2.

Ainsi, la dérivée de tan(x)^jest

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

Ainsi, les contributeurs à tan(x)^jla idérivée e sont tan(x)^(j-1)et tan(x)^(j+1)à la (i-1)dérivée st, chacun avec un coefficient égal à sa puissance.


3

Gelée , 12 11 octets

Ṛ+\;S
ḂÇ⁸¡Ḣ

Comme la réponse CJam de Peter Taylor , cela calcule le n ème terme de la séquence haut / bas d' Euler si n est impair et les cas spéciaux même n égal à 0 .

Essayez-le en ligne! ou vérifier tous les cas de test .

Comment ça fonctionne

ḂÇ⁸¡Ḣ  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

Sauge, 26 octets

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

Comme les autres solutions dans les langages mathématiques, cette fonction calcule la ndérivée e de tan(x)et l'évalue à x = 0.

Essayez-le en ligne


2

J, 15 13 octets

Il y a aussi la fonction intégrée t:qui calcule le n ième coefficient de la fonction de génération exponentielle de tan (x) .

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

Merci à @ Leaky Nun de m'avoir rappelé les adverbes de la série Taylor en J qui ont sauvé 2 octets.

Alternative pour 15 octets .

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

Une autre approche consiste à calculer le n ème dérivée de tan (x) et à l'évaluer à x = 0 .

Remarque: dans J , la quantité de mémoire utilisée par la fonction dérivée d.augmente rapidement lorsque n passe à 10.

Usage

   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

Explication

(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 octets

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

Enregistré 2 octets grâce à Dennis.

Pas la solution la plus courte de Julia (voir la solution de Dennis), mais celle-ci se fait uniquement en utilisant une logique dérivée ... sous forme de matrices.

Fondamentalement, il utilise le fait que la dérivée de tan (x) est 1 + tan (x) ^ 2. Donc, puisque la dérivée de toute puissance de tan (x), disons tan (x) ^ k, est k tan (x) ^ (k-1) tan (x) '= k tan (x) ^ (k-1) + k tan (x) ^ (k + 1), nous pouvons utiliser une puissance de matrice simple sur une matrice avec les valeurs appropriées pour générer l'expansion, la deuxième ligne ou colonne (selon la construction) contenant les dérivés de tan (x ) lui-même.

Il nous suffit donc de trouver la constante dans l'expression résultante, et c'est la première valeur de la ligne ou de la colonne correspondante.


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

@Dennis - belle prise. Je ne savais pas que spdiagmcela permettrait ce style de construction - diagmje l'ai essayé , mais bien sûr, cela n'a pas fonctionné.
Glen O

2

JavaScript (ES6), 127 45 octets

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

Port des solutions @ xnor.


0

Haskell, 95 93 octets

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

Il s'agit essentiellement d'une implémentation de la formule générale avec quelques optimisations mineures.


0

MATLAB avec Symbolic Toolbox, 84 octets

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

L'exemple s'exécute:

>> 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 (trop d'octets)

En utilisant uniquement les opérations sur les listes et le résultat de 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])

Malheureusement, cela déborde pour des valeurs modestes de n, car il utilise des Intvaleurs. Je vais essayer de résoudre le problème en utilisant des Integervaleurs. D'ici là, les suggestions sont les bienvenues.


0

Axiome, 46 octets

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

code pour test et résultats

(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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.