"Convergência" harmoniosa

16

A série harmônica alternada é uma série convergente bem conhecida.

1/1 - 1/2 + 1/3 - 1/4 + 1/5 - 1/6 + ...

"Claramente", é óbvio que converge para o logaritmo natural de 2. Ou é?

Como a série não é absolutamente convergente , basta reorganizar os termos, posso fazer com que ela se aproxime do que eu quiser. Suponha que eu queira que a série converja para e . Tudo o que eu teria que fazer é o seguinte:

1/1 + 1/3 + ... + 1/65 - 1/2 + 1/67 + ... + 1/175 - 1/4

Se você não capturou o padrão, não existe um óbvio. Veja como funciona:

  1. Considere os termos da série harmônica alternada em termos positivos e negativos.
  2. Adicione apenas termos positivos suficientes para exceder nossa meta (e). (aka sum > target)
  3. Subtraia o próximo termo negativo.
  4. Volte para 2.

Observe que na etapa 2, se for o caso sum == target, você deve adicionar outro termo positivo.

A partir disso, podemos definir uma sequência associada a cada número da seguinte maneira:

  • Siga o algoritmo acima
  • Para cada termo positivo, produto 1.
  • Para cada termo negativo, produza 0.

Vamos chamar essa sequência de "Padrão de bits harmonioso" de um número. Por exemplo, o HBP de e começa como:

1, 1, 1, 1, <32 times>, 0, 1, 1, <54 times>, 0, 1, 1, ...

Seu desafio:

Você receberá:

  • um alvo de entrada racional no intervalo [-10, 10] (nota: até atingir 10 através da série harmônica requer muitos milhões de termos). Pode ser um decimal (aka 1.1) ou você pode usar um racional diretamente (aka 12/100)
  • uma entrada int n positiva , especificando o número de termos do Padrão de bits harmonioso a serem emitidos.

Espera-se que você envie o padrão de bits harmonioso exato do destino para o número especificado de termos. Você pode gerar valores separados por espaço, separados por vírgula, sem separação, etc; desde que o padrão de 0s e 1s seja claramente visível e lido da esquerda para a direita com uma separação consistente.

Casos de teste

>>> 0, 1
1
>>> 0, 2
10
>>> 0, 7
1000010
>>> 1, 10
1101011011
>>> 1.01, 3
110
>>> 1.01, 24
110101101101101101101101
>>> 2.71, 32
11111111111111111111111111111111
>>> 2.71, 144
111111111111111111111111111111110111111111111111111111111111111111111111111111111111111101111111111111111111111111111111111111111111111111111111
>>> -9.8, 100
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Observe que, como -9.8é muito grande, o primeiro 1resultado seria algo em torno do 149496620termo th (que foi calculado por meio de flutuadores, portanto, o valor pode não ser exato).

Justin
fonte

Respostas:

3

Perl, 69 bytes

use bigrat;$s+=.5/($s>$ARGV[$_=0]?-++$n:++$p-++$_/2),print for 1..pop

Recebe entradas como argumentos de linha de comando.

Explicação : bigratativa frações em todos os lugares para cálculos precisos. $sé a soma atual dos termos, $ARGV[0]é o valor alvo, pop(o mesmo que $ARGV[1]) representa o número de termos $pe $nrepresenta as contagens de termos positivos e negativos. $_é 1ou 0depende se um termo positivo ou negativo foi adicionado.

svsd
fonte
3

Haskell, 92 91 90 bytes

import Data.Ratio
f=(.h 0 1 2).take
h a p q z|a>z=0:h(a-1%q)p(q+2)z|1<2=1:h(a+1%p)(p+2)q z

Exemplo de uso: f 24 1.01-> [1,1,0,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1,1,0,1].

hconstrói o padrão de bits infinito carregando quatro parâmetros: aé a soma atual. pé o denominador do próximo termo positivo, qpara termos negativos. zé o número de destino. finicia tudo e trunca o resultado n.

Edit: @Zgarb encontrou um byte para salvar. Obrigado!

nimi
fonte
Definir em h a p qvez de h p q asalva um byte.
Zgarb
Deve-se notar que 7 bytes são gastos apenas aparando a lista de resultados infinitos para uma de comprimento n . Na verdade, seria muito melhor fornecer apenas a lista infinita como resultado.
deixou de girar contra-
1

Python 3, 128 124 bytes

from fractions import*
F=Fraction
*c,s=2,1,0
t=F(input())
for i in'x'*int(input()):w=s<=t;s+=F(w*2-1,c[w]);c[w]+=2;print(+w)

Isso faz uso da Fractionclasse do Python .

from fractions import* 
F=Fraction
*c,s=2,1,0                # c = [2, 1]. s = 0
                          # c is my positive/negative term counter, s is the sum
t=F(input())              # input a fraction
for i in'x'*int(input()): # Do this for for the chosen number of terms, as per the spec
  w=s<=t;                 # "w" or which one do we choose? Positive or negative?
  s+=F(w*2-1,c[w]);       # w*2-1 gives 1 if w else -1. Gives 1 if we need to add, else -1
  c[w]+=2;                # Increment the coefficient we chose
  print(+w)               # Output that. The +w coerces the bool to an int.
Justin
fonte
11
'x'*int(input())?
FryAmTheEggman