"Convergencia" armoniosa

16

La serie armónica alterna es una serie convergente bien conocida.

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

"Claramente", es obvio que converge al registro natural de 2. ¿O no?

Como la serie no es absolutamente convergente , simplemente reorganizando los términos, puedo hacer que se acerque a lo que quiera. Supongamos que quiero que la serie converja a e . Todo lo que tendría que hacer es esto:

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

Si no captó el patrón, no hay uno obvio. Así es como funciona:

  1. Considere los términos de la serie armónica alterna en términos de términos positivos y negativos.
  2. Agregue los términos positivos suficientes para superar nuestro objetivo (e). (aka sum > target)
  3. Resta el siguiente término negativo.
  4. Regrese a 2.

Tenga en cuenta que en el paso 2, si es nuestro sum == target, debe agregar otro término positivo.

A partir de esto, podemos definir una secuencia asociada con cada número de la siguiente manera:

  • Sigue el algoritmo de arriba
  • Para cada término positivo, salida 1.
  • Para cada término negativo, salida 0.

Llamemos a esta secuencia el "Patrón de bits armonioso" de un número. Por ejemplo, el HBP de e comienza como:

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

Tu reto:

Se le dará:

  • un objetivo de entrada racional en el rango [-10, 10] (nota: incluso alcanzar 10 a través de la serie armónica requiere muchos millones de términos). Esto puede ser un decimal (aka 1.1) o puede tomar un racional directamente (aka 12/100)
  • una entrada int n positiva , que especifica el número de términos del patrón de bits armonioso para la salida.

Se espera que envíe el patrón de bits armonioso exacto del objetivo al número especificado de términos. Puede generar valores separados por espacios, separados por comas, sin separación, etc. siempre y cuando el patrón de 0s y 1s sea claramente visible y se lea de izquierda a derecha con una separación constante.

Casos de prueba

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

Tenga en cuenta que, dado que -9.8es tan grande, lo primero 1que se generaría es en algún lugar alrededor del 149496620término th (que se calculó mediante flotantes, por lo que el valor podría no ser exacto).

Justin
fuente

Respuestas:

3

Perl, 69 bytes

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

Toma entradas como argumentos de línea de comando.

Explicación : bigrathabilita fracciones en todas partes para cálculos precisos. $ses la suma actual de términos, $ARGV[0]es el valor objetivo, pop(igual que $ARGV[1]) representa el número de términos $py $nrepresenta los recuentos de términos positivos y negativos. $_es o bien 1o 0dependiendo de si se añadió un término positivo o negativo.

svsd
fuente
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

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

hconstruye el patrón de bits infinito llevando cuatro parámetros: aes la suma actual. pes el denominador del siguiente término positivo, qpara términos negativos. zes el número objetivo finicia todo y trunca el resultado a la longitud n.

Editar: @Zgarb encontró un byte para guardar. ¡Gracias!

nimi
fuente
Definir en h a p qlugar de h p q aguardar un byte.
Zgarb
Debe tenerse en cuenta que se gastan 7 bytes en solo recortar la lista de resultados infinitos a uno de longitud n . En realidad, sería mucho mejor simplemente dar la lista infinita como resultado.
dejó de girar en sentido contrario a las agujas del reloj el
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)

Esto hace uso de la Fractionclase de 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
fuente
1
'x'*int(input())?
FryAmTheEggman