CJam (69 bytes)
]qi:X,{1e|,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/W\+_1,*X=\_W%.*:+-Y/z
Demonstração online
Explicação
A idéia básica é implementar a função geradora descrita em OEIS. A entrada é um caso especial desagradável, mas os ajustes finais que fiz acabaram produzindo para esse caso, então o (para valor absoluto) o arruma. Esse é o truque mais estranho aqui.0−1z
.*:+
é repetido três vezes e parece que poderia salvar um byte se extraído como {.*:+}:F~
. No entanto, isso rompe com o caso especial , porque não executa o loop externo.0
Usamos a função de geração auxiliar para A000081 , cujos termos têm a recorrência
a[0] = 0
a[1] = 1
For n >= 1, a[n+1] = (sum_{k=1}^n a[n-k+1] * sum_{d|k} d * a[d]) / n
Eu tenho certeza que algumas linguagens possuem built-ins para a transformação inversa de Möbius , mas o CJam não; a melhor abordagem que eu encontrei é para construir um conjunto de mapeamento para e, em seguida, fazer uma multiplicação pontual com utilização . Observe que aqui é conveniente criar partida no índice 1, porque queremos evitar a divisão por zero ao configurar os pesos. Observe também que se as duas matrizes fornecidas para a operação apontada não tiverem o mesmo comprimento, os valores da mais longa permanecerão intocados: portanto, temos que pegar os primeiros termos de ou fazer com que a matriz de pesos suba para∑d∣kd×a[d]dk % d == 0 ? d : 0
a.*
akan. O último parece mais curto. Portanto, essa transformação inversa de Möbius é responsável porN\f{1$%!*}W$.*:+
Se chamarmos o resultado da transformação inversa de Möbius M
, agora temos
a[n+1]=1n∑k=1na[n−k+1]×M[k]
Obviamente, o numerador é um termo de uma convolução, para que possamos manipulá-lo revertendo uma cópia de ou e, em seguida, efetuando uma multiplicação e soma pontual. Novamente, nosso índice varia de a e, além disso, queremos emparelhar índices que somam , por isso é conveniente indexar de 1 em vez de 0. Agora, respondemos poraM1nn+1a
qi:X,{ ,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/
O ponto da função auxiliar de geração é dado pela seção de fórmula de A000055:
G.f.: A(x) = 1 + T(x) - T^2(x)/2 + T(x^2)/2,
where T(x) = x + x^2 + 2*x^3 + ... is the g.f. for A000081.
Em termos de , isso significa que a saída que buscamos éa
[x=0]+a[x]+12(a[x/2]−∑i=0na[i]×a[n−i])
onde para com ímpar obtemos 0. A maneira mais curta que encontrei para fazer isso é inflar com zeros ( ) e depois pegar o Xº elemento ( ).a[x/2]x1,*
X=
Observe que a soma é mais uma convolução, mas desta vez é conveniente indexar a partir de 0. A solução óbvia é 0\+
, mas há uma ótima otimização aqui. Como , dois termos da convolução são garantidos como zero. Podemos aproveitar isso como uma oportunidade para indexar a partir de 1, mas o caso especial fica feio. Se o fizermos , a convolução nos dará e após a subtração e divisão por lidamos com o termo a fora da soma também.a[0]=0X=0W\+
−2a[x]+∑ni=0a[i]×a[n−i]2a[x]
Então nós explicamos
qi:X,{ ,:):N{N\f{1$%!*}W$.*:+}%1$W%.*:+N,/+}/W\+_1,*X=\_W%.*:+-Y/
Os demais detalhes estão relacionados ao caso especial. Originalmente, segui a recorrência mais estritamente começando 1]
e iterando de comN=1
1]qi:X,1>{ ... }/
O resultado quando é que computamos como : um termo a mais do que precisamos. A inflação e a convolução acabam dando um resultado de . (Talvez melhor do que merecemos - é o que deveríamos ter, porque não fizemos nada sobre o termo ). Portanto, corrigimos isso para três caracteres como final ou usando a técnica padrão de "fallback" como .X=0a[-1 1]
0[x=0]X!+
1e|
Para obter o comprimento "certo" de , precisamos evitar o fornecimento iniciala1N=0
]qi:X,{ ... /+}/
obviamente dá divisão por zero. Mas se tentarmos
]qi:X,{1e| ... /+}/
então funciona. Nós temos
e# Stack: [] 0
1e| e# Stack: [] 1
,:):N e# Stack: [] [1]
{ e# We only execute this loop once
N\f{1$%!*} e# 1 divides 1, so stack: [] [1]
W$.* e# Remember: if the two arrays supplied to the pointwise operation
e# are not the same length then the values from the longer one are
e# left untouched. Stack: [] [1]
:+ e# Fold over a singleton. Stack: [] 1
}% e# And that was a map, so stack: [] [1]
1$W%.*:+ e# Another [1] [] .*:+, giving the same result: 1
N,/ e# 1 / 1 = 1
+ e# And we append 1 to a giving [1]
que produz exatamente o valor que exigimos.
X=0−1[-1]
(−1−12(−1×−1))=−101−11z