Trova i coefficienti di una funzione generatrice razionale


12

Se scriviamo una sequenza di numeri come coefficienti di una serie di potenze, allora quella serie di potenze viene chiamata funzione (ordinaria) di generazione (o Gf) di quella sequenza. Cioè, se per alcune funzioni F(x)e serie di numeri interi a(n)abbiamo:

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

Quindi F(x)è la funzione generatrice di a. Ad esempio, la serie geometrica ci dice che:

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

Quindi la funzione generatrice di 1, 1, 1, ...è 1/(1-x). Se differenziamo entrambi i lati dell'equazione sopra e moltiplichiamo per xotteniamo la seguente uguaglianza:

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

Quindi la funzione generatrice di 1, 2, 3, ...è x/(1-x)^2. La generazione di funzioni è uno strumento molto potente e puoi fare molte cose utili con esse. Una breve introduzione può essere trovata qui , ma per una spiegazione davvero approfondita c'è l'incredibile generologia del libro.


In questa sfida assumerai una funzione razionale (il quoziente di due polinomi con coefficienti interi) come input come due matrici di coefficienti interi, prima il numeratore e poi il denominatore. Ad esempio, la funzione f(x) = x / (1 - x - x^2)verrà codificata come [0, 1], [1, -1, -1]nell'input.

Dato questo input, il programma deve stampare all'infinito i coefficienti della serie di potenze che è uguale alla funzione di generazione, una per riga, a partire dal coefficiente di x, quindi x^2, ecc.


Esempi:

[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, il mio linguaggio è costruito per le sequenze di questo, ma non posso davvero fare input di array multidimensionali :(
Stephen

2
In realtà non sono abbastanza mentalmente abbastanza matematico per questa specifica, qualche possibilità che potresti pubblicare più delle spiegazioni di un laico per noi gente comune?
Skidsdev,


1
@trichoplax Ciò forza sempre il numeratore a 1, che non è lo stesso. Ad esempio non può esprimere il mio ultimo esempio, i quadrati.
orlp,

1
Un modo alternativo di formulare questo è che valuta una ricorrenza lineare generale. In questo modo generalizza questa domanda e potrebbe servire come bersaglio duplice per future domande di ricorrenza.
Peter Taylor,

Risposte:


7

Haskell , 63 byte

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

Provalo online!

Definisce un operatore che %restituisce un elenco pigro infinito di coefficienti. L'elenco è a zero, quindi è incluso il coefficiente costante.


3

Mathematica, 64 83 90 byte

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

Grazie a @ngenisis e @Jenny_mathy!

Prendi input come due elenchi.

È necessario Alt+.terminare l'esecuzione per vedere il risultato. Il frontend potrebbe bloccarsi a causa dell'output rapido.

Versione da 83 byte (@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 byte: i = 1; v = Tr [# * x ^ Intervallo @ Lunghezza @ #] &; Mentre [1 <2, Echo @ Limit [D [v @ # / v @ # 2 / i !, {x, i}], x -> 0]; i ++] &
J42161217

@Jenny_mathy Ci scusiamo per il disturbo. Ho capito che ci sono alcuni caratteri Unicode invisibili spazzatura nel tuo primo commento. Una volta ripulito, il codice è OK.
Keyu Gan,

3
64bytes: Do[Echo@Limit[D[#/#2/i!&@@Fold[x#+#2&]/@#,{x,i}],x->0],{i,∞}]&. Ciò presuppone che l'ingresso sia un elenco di due elenchi e che i coefficienti siano in ordine decrescente. L'unico built-in che conosco per fare ciò che vfa èInternal`FromCoefficientList
ngenisis,

L'esecuzione ripetuta funziona? Penso che potrebbe essere necessario un paio di parentesi extra da inserire iall'interno della lambda. (D'altra parte, non sono davvero sicuro se la capacità di correre ripetutamente sia rilevante quando l'obiettivo è quello di stampare un elenco infinito ... c'è stato un meta consenso su questo?)
Julian Wolf,

@ngenisis: quale versione stai usando? Su v10.0, la tua soluzione mi dà Iterator {i,∞} does not have appropriate bounds.
Julian Wolf,

1

CJam (22 byte)

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

Demo online . Si noti che come molte delle risposte esistenti, questo include il 0o coefficiente nell'output.

Dissezione

{           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 byte

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

Accetta input come due elenchi separati (coefficienti numeratori, coefficienti denominatori). Se l'input può essere preso direttamente come una frazione di polinomi piuttosto che come elenchi di coefficienti, questo può essere abbreviato in modo significativo.

Sembra che Dopossa funzionare con limiti infiniti in v11. Non posso verificarlo localmente, ma, in questo caso, questa soluzione può essere abbreviata a 75 byte :

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

l'ultimo caso di test non inizia con 0.
J42161217

@Jenny_mathy: scatta, grazie per l'heads up. Sembra che i casi di test si aspettino a partire dal primo al posto dello zeroth ... abbastanza sicuro che questo dovrebbe farmi risparmiare qualche byte.
Julian Wolf,

@Jenny_mathy: penso che i casi di test possano essere traballanti. A partire nda 1 invece di 0, questo dà gli stessi risultati della tua soluzione; entrambi falliscono, tuttavia, sul penultimo test case, che questa soluzione passa quando inizia nda 0.
Julian Wolf

0

Pyth , 23 byte

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

Provalo online!

Come funziona

                       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

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.