Golf a sequência cuja função de geração exponencial é tangente


15

Quase todas as funções podem ser expressas como um polinômio com termos infinitos.

Por exemplo, e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! + ...

Por exemplo, sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...

Os coeficientes dos n-ésimos termos formam uma sequência e a função correspondente é chamada de Função Geradora da sequência.

Os coeficientes da n -ésimos termos formam uma sequência.

Freqüentemente, o n-ésimo termo teria um denominador de n!. Portanto, multiplicamos o coeficiente por n!para obter outra sequência, cuja Função Geradora Exponencial seria a função original.

Por exemplo, a sequência cuja função de geração exponencial é e^xseria1,1,1,1,... .

Por exemplo, a sequência cuja função de geração exponencial é sin(x)seria0,1,0,-1,0,1,0,-1,... .

Tarefa

Sua tarefa é encontrar o n-ésimo termo da sequência cuja Função Geradora Exponencial é tan(x).

Casos de teste

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

(Copiado daqui .) (Aviso: o 0termo-é diferente)

Implementação de exemplo

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

Referências


4
Se você quiser aprender mais sobre a geração de funções e seu uso em matemática, especialmente combinatória e teoria dos números, eu recomendo este "famoso" livro didático de geração de funcionalidade, de H. Wilf.
flawr

5
(Não consigo resistir): tomada literalmente, sua primeira frase é extremamente falsa!
Solha

Você tem o significado de "função geradora" e "função geradora exponencial" ao contrário. $ \ sin (x) $ é a função geradora exponencial da sequência 0,1,0, -1,0,1,0, -1,0, ... - não é a sequência que é a função geradora exponencial de $ \ sin (x) $. O que você está nos pedindo para fazer é codificar a sequência gerada exponencialmente por $ \ tan (x) $.
Glen O

Parece bom, exceto "Isso também é chamado de função geradora dessa função. Os coeficientes dos enésimos termos são uma sequência", que provavelmente deveria dizer algo como "Os coeficientes dos enésimos termos formam uma sequência, e a função correspondente é chamada de função geradora da sequência ".
Glen O

@GlenO Edited.
Leaky Nun

Respostas:


8

CJam ( 33 32 27 26 23 20 bytes)

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

Demonstração online

Dissecação

Isso basicamente implementa a recorrência descrita pelo 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 com uma abordagem bastante diferente, para 23 bytes:

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

Demonstração online . Agradecimentos a Dennis por 3 bytes.

Dissecação

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 com uma abordagem muito diferente, para 29 bytes:

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

Demonstração online

Infelizmente, é necessário um caso especial para entrada 0 .

Dissecação

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

Você pode estar pensando "WTF ?! Ele está respondendo à pergunta errada." Nesse caso, isso é compreensível, mas as duas abordagens realmente fornecem os resultados corretos .


Caso isso ajude, a compilação noturna no TIO retorna uma matriz vazia para [WW]3ew.
Dennis

@ Dennis, obrigado. No entanto, acontece que 0precisa ser um caso especial de qualquer maneira, porque avalia como 1.
Peter Taylor

1
Alguém poderia pensar que você está respondendo à pergunta errada, se nem sequer clicou nos meus links.
Leaky Nun

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

2
@LeakyNun, então seriam todos então. Eu vi essa lista de links e tl; dr.
Peter Taylor

7

Julia, 40 38 32 bytes

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

Entrada e saída está na forma de BigFloats. Experimente online!

fundo

A série Maclaurin da função tangente satisfaz a identidade

sempre que x estiver no seu raio de convergência, onde B n é um número de Bernoulli.

Como B 2 (n + 1) e (-1) n têm o mesmo sinal, B 2n + 1 = 0 se n> 0 e B 1 = 1/2 , podemos reescrever o que foi descrito a seguir.

Além disso, sempre que n é um número inteiro não negativo, temos

onde ζ denota a função Riemann zeta .

A partir disso, com a convenção 0 0 = 1 , segue-se que

qual é a fórmula que a implementação usa.


6

Python, 57 bytes

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

Menos golfe:

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)

Podemos calcular o ith coeficiente da função geradora exponencial diferenciando os itempos da função tangente e avaliando em 0. Cada derivada é um polinômio em tan(x), e seu valor em 0 é seu termo constante.

Nós recursivamente expressar o coeficiente de tan(x)**jno ith derivado de tancom a função f(i,j). A expressão recursiva vem da relação tan(x)' = 1 + tan(x)**2.

Então, a derivada de tan(x)**jé

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

Portanto, os contribuintes tan(x)**jna iderivada th são tan(x)**(j-1)e tan(x)**(j+1)na (i-1)derivada st, cada um com coeficiente igual ao seu poder. Isso dá a expressão recursiva

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

Observe que não precisamos excluir expoentes negativos jporque eles avaliam a zero de qualquer maneira e não contribuem porque o cruzamento j=0fornece um multiplicador de 0.

O caso base de i==0corresponde a tan(x)si mesmo com j==1, e coeficientes zero, caso contrário. A avaliação final ocorre no termo constante j=0, que é inserido como um valor padrão.


Isso leva para 20 bytes no CJam. Você se importa se eu fizer essa a minha resposta principal ou você deseja portá-la e publicá-la?
Peter Taylor

Você deve publicá-lo, eu não sei CJam.
xnor

4

Mathematica, 20 bytes

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

Abordagem direta. Calcule a n- ésima derivada de tan (x) e avalie-a em x = 0 .

Uso

Exemplo


3

Haskell, 48 bytes

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

Podemos calcular o icoeficiente th da função geradora exponencial diferenciando a função tangentei tempos da e avaliando em 0. Cada derivada é um polinômio em tan(x), e o valor em 0 é seu termo constante.

Expressamos recursivamente o coeficiente de tan(x)^jna ith derivada detan com a função i%j. A expressão recursiva vem da relaçãotan(x)' = 1 + tan(x)^2.

Então, a derivada de tan(x)^jé

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

Portanto, os contribuintes tan(x)^jna iderivada th são tan(x)^(j-1)e tan(x)^(j+1)na (i-1)derivada st, cada um com coeficiente igual ao seu poder.


3

Geléia , 12 11 bytes

Ṛ+\;S
ḂÇ⁸¡Ḣ

Como resposta CJam de Peter Taylor , este calcula o n º prazo de Euler é para cima / baixo seqüência , se n é ímpar e-casos especiais ainda n como 0 .

Experimente online! ou verifique todos os casos de teste .

Como funciona

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

Sábio, 26 bytes

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

Como as outras soluções em linguagens orientadas à matemática, essa função calcula a nth-derivada de tan(x)e a avalia emx = 0 .

Experimente online


2

J, 15 13 bytes

Há também o embutido t:que calcula o n th coeficiente da função geradora exponencial de tan (x) .

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

Agradeço ao @ Leaky Nun por me lembrar dos advérbios da série Taylor em J que salvaram 2 bytes.

Alternativa para 15 bytes .

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

Outra abordagem é calcular a n- ésima derivada de tan (x) e avaliá-la em x = 0 .

Nota: Em J , a quantidade de memória usada pela função derivada d.cresce rapidamente quando 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

Explicação

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

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

Economizou 2 bytes graças a Dennis.

Não é a solução mais curta de Julia (veja a solução de Dennis), mas essa é feita puramente usando lógica derivada ... na forma de matrizes.

Basicamente, usa o fato de que a derivada de tan (x) é 1 + tan (x) ^ 2. Então, como a derivada de qualquer potência de tan (x), digamos tan (x) ^ k, é k tan (x) ^ (k-1) tan (x) '= k tan (x) ^ (k-1) + k tan (x) ^ (k + 1), podemos usar uma potência de matriz simples em uma matriz com os valores apropriados para gerar a expansão, com a segunda linha ou coluna (dependendo da construção) segurando os derivados de tan (x ) em si.

Então, só precisamos encontrar a constante na expressão resultante, e esse é o primeiro valor na linha ou coluna correspondente.


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

@ Dennis - boa captura. Não sabia spdiagmque permitiria esse estilo de construção - tentei com isso diagm, mas é claro que não funcionou.
Glen O

2

JavaScript (ES6), 127 45 bytes

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

Porto das soluções da @ xnor.


0

Haskell, 95 93 bytes

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

É basicamente uma implementação da fórmula geral com algumas otimizações menores.


0

MATLAB com caixa de ferramentas simbólica, 84 bytes

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

Exemplo é executado:

>> 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 (muitos bytes)

Usando apenas operações em listas e o resultado 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])

Infelizmente, isso excede os valores modestos de n, pois usa Intvalores. Vou tentar corrigir o problema usando Integervalores. Até lá, sugestões são bem-vindas.


0

Axioma, 46 bytes

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

código para teste e resultados

(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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.