Encontre os coeficientes de uma função geradora racional


12

Se escrevermos uma sequência de números como coeficientes de uma série de potências, essa série de potências será chamada de função geradora (comum) (ou Gf) dessa sequência. Ou seja, se, para alguma função F(x)e série de números inteiros a(n), temos:

a(0) + a(1)x + a(2)x^2 + a(3)x^3 + a(4)x^4 + ... = F(x)

Então F(x)é a função geradora de a. Por exemplo, a série geométrica nos diz que:

1 + x + x^2 + x^3 + x^4 + ... = 1/(1-x)

Portanto, a função geradora de 1, 1, 1, ...é 1/(1-x). Se diferenciarmos ambos os lados da equação acima e multiplicarmos x, obtemos a seguinte igualdade:

x + 2x^2 + 3x^3 + 4x^4 + ... = x/(1-x)^2

Portanto, a função geradora de 1, 2, 3, ...é x/(1-x)^2. A geração de funções é uma ferramenta muito poderosa e você pode fazer muitas coisas úteis com elas. Uma breve introdução pode ser encontrada aqui , mas para uma explicação realmente completa, há o incrível livro que gera a funcionalidade.


Nesse desafio, você terá uma função racional (o quociente de dois polinômios com coeficientes inteiros) como entrada como duas matrizes de coeficientes inteiros, primeiro o numerador e o denominador. Por exemplo, a função f(x) = x / (1 - x - x^2)será codificada como [0, 1], [1, -1, -1]na entrada.

Dada essa entrada, seu programa deve imprimir infinitamente os coeficientes da série de potências que são iguais à função geradora, um por linha, começando no coeficiente de x, então x^2, etc.


Exemplos:

[1], [1, -1] -> 1, 1, 1, 1, 1, 1, 1, ...
[1], [2, -2] -> 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, ...
[0, 1], [1, -2, 1] -> 1, 2, 3, 4, 5, 6, 7, 8, ...
[0, 1], [1, -1, -1] -> 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
[1], [1, -2] -> 1, 2, 4, 8, 16, 32, 64, 128, ...
[0, 1, 1], [1, -3, 3, -1] -> 1, 4, 9, 16, 25, 36, ...

Merda, minha língua é construída para seqüências isso, mas eu realmente não pode fazer entrada de matriz multidimensional :(
Stephen

2
Na verdade, eu não sou matemático o suficiente para essa especificação, alguma chance de você postar mais explicações de leigos para nós, gente comum?
Skidsdev 07/07


1
@trichoplax Isso sempre força o numerador a 1, o que não é o mesmo. Por exemplo, não pode expressar meu último exemplo, os quadrados.
orlp

1
Uma maneira alternativa de expressar isso é que ele avalia uma recorrência linear geral. Dessa forma, ele generaliza essa questão e pode servir como um alvo idiota para futuras questões de recorrência.
Peter Taylor

Respostas:


7

Haskell , 63 bytes

z=0:z
(a:b)%y@(c:d)=a/c:zipWith(-)(b++z)(map(a/c*)d++z)%y
_%_=z

Experimente online!

Define um operador %retornando uma lista lenta infinita de coeficientes. A lista é indexada a zero, portanto, o coeficiente constante é incluído.


3

Mathematica, 64 83 90 bytes

Do[Echo@Limit[D[#/#2/i!&@@Fold[x#+#2&]/@#,{x,i}],x->0],{i,∞}‌​]&

Obrigado a @ngenisis e @Jenny_mathy!

Tome entrada como duas listas.

Precisa Alt+.finalizar a execução para ver o resultado. O front-end pode falhar devido à saída rápida.

Versão de 83 bytes (@Jenny_mathy):

i=1;v=Tr[#*x^Range@Length@#]&;While[1<2,Echo@Limit[D[v@#/v@#2/i!,{x,i}],x->0];i++]&

83 bytes: i = 1; v = Tr [# * x ^ Intervalo @ Comprimento @ #] &; Enquanto [1 <2, Limite de Eco @ [D [v @ # / v @ # 2 / i !, {x, i}], x -> 0]; i ++] &
J42161217 07/07

@Jenny_mathy Desculpe por incomodar. Descobri que há alguns caracteres Unicode invisíveis em seu primeiro comentário. Depois de limpo, o código está OK.
Keyu Gan

3
64bytes: Do[Echo@Limit[D[#/#2/i!&@@Fold[x#+#2&]/@#,{x,i}],x->0],{i,∞}]&. Isso pressupõe que a entrada seja uma lista de duas listas e os coeficientes estejam em ordem decrescente. A única built-in que conheço para fazer o que vfaz éInternal`FromCoefficientList
ngenisis

A execução repetida disso funciona? Eu acho que alguns parênteses extras podem ser necessários para colocar identro da lambda. (Por outro lado, não tenho muita certeza se a capacidade de executar repetidamente é relevante quando o objetivo é imprimir uma lista infinita ... houve um meta consenso sobre isso?)
Julian Wolf

@ngenisis: Qual versão você está usando? Na v10.0, sua solução me fornece Iterator {i,∞} does not have appropriate bounds.
Julian Lobo

1

CJam (22 bytes)

{\{(W$(@\/_pW*f*.+1}g}

Demonstração online . Observe que, como muitas das respostas existentes, isso inclui o coeficiente 0 na saída.

Dissecação

{           e# Define a block which takes numerator N and denominator D as arguments
  \         e# Flip to put D at the bottom, since that won't change
  {         e# Infinite loop:
    (       e#   Pop the first element of (the modified) N
    W$(     e#   Copy D and pop its first element
            e#   Stack: D N[1:] N[0] D[1:] D[0]
    @\/     e#   Bring N[0] to top, flip, divide
            e#   Stack: D N[1:] D[1:] N[0]/D[0]
    _p      e#   Print a copy
    W*f*.+  e#   Multiply by -1, multiply all, pointwise add
            e#   Stack: D N[1:]-(N[0]/D[0])*D[1:]
  1}g
}

0

Mathematica, 86 79 bytes

f=x^Range@Length@#.#&;For[n=1,8>3,Print@SeriesCoefficient[f@#/f@#2,{x,0,n++}]]&

Recebe entrada como duas listas separadas (coeficientes do numerador, coeficientes do denominador). Se a entrada puder ser tomada diretamente como uma fração de polinômios, e não como listas de coeficientes, isso poderá ser reduzido significativamente.

Parece que Dopode funcionar com limites infinitos na v11. Não posso testar isso localmente, mas, se for esse o caso, essa solução pode ser reduzida para 75 bytes :

f=x^Range@Length@#.#&;Do[Print@SeriesCoefficient[f@#/f@#2,{x,0,n}],{n,∞}]&

o último caso de teste não começa com 0.
J42161217 07/07

@ Jenny_mathy: atire, obrigado pelo aviso. Parece que os casos de teste esperam começar do primeiro em vez do zeroth ... com certeza isso deve me permitir salvar alguns bytes.
Julian Wolf

@ Jenny_mathy: Eu acho que os casos de teste podem ser instáveis. A npartir de 1 em vez de 0, isso fornece os mesmos resultados que sua solução; ambos falham, no entanto, no penúltimo caso de teste, que esta solução passa ao iniciar a npartir de 0.
Julian Wolf

0

Pitão , 23 bytes

JE#
KchQhJ=t-M.t,Q*LKJ0

Experimente online!

Como funciona

                       Q = eval(input())
JE                     J = eval(input())
  #                    infinite loop:
 chQhJ                   Q[0]/J[0]
K                        assign that to K (and print it, because of the preceding newline)
              *LKJ       K times every element of J
            ,Q           [Q, that]
          .t      0      transpose, padding with 0s
        -M               subtract each pair
       t                 remove the first element
      =                  assign that back to Q

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.