«Convergence» harmonieuse

16

La série harmonique alternée est une série convergente bien connue.

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

"Clairement", il est évident qu'il converge vers le logarithme naturel de 2. Ou est-ce le cas?

Puisque la série n'est pas absolument convergente , en réorganisant simplement les termes, je peux la faire approcher de tout ce que je veux. Supposons que je veuille que la série converge vers e . Tout ce que je devrais faire, c'est ceci:

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

Si vous n'avez pas saisi le motif, il n'y en a pas d'évident. Voici comment ça fonctionne:

  1. Considérez les termes de la série harmonique alternée en termes de termes positifs et négatifs.
  2. Additionnez juste assez de termes positifs pour dépasser notre objectif (e). (aka sum > target)
  3. Soustrayez le prochain terme négatif.
  4. Revenez à 2.

Notez qu'à l'étape 2, si notre sum == target, vous devez ajouter un autre terme positif.

À partir de cela, nous pouvons définir une séquence associée à chaque numéro comme suit:

  • Suivez l'algorithme ci-dessus
  • Pour chaque terme positif, sortie 1.
  • Pour chaque terme négatif, affichez 0.

Appelons cette séquence le "motif binaire harmonieux" d'un nombre. Par exemple, le RAP de e commence comme suit:

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

Votre défi:

Vous recevrez:

  • une cible d' entrée rationnelle dans la gamme [-10, 10] (note: même atteindre 10 via la série harmonique prend plusieurs millions de termes). Cela peut être une décimale (aka 1.1) ou vous pouvez prendre un rationnel directement (aka 12/100)
  • une entrée int n positive , spécifiant le nombre de termes du modèle de bit harmonique à sortir.

Vous devez générer le modèle de bits harmonieux exact de la cible selon le nombre de termes spécifié. Vous pouvez sortir des valeurs séparées par des espaces, séparées par des virgules, pas de séparation, etc; tant que le motif de 0 et de 1 est clairement visible et est lu de gauche à droite avec une séparation cohérente.

Cas de test

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

Notez que puisque -9.8est si grand, le premier 1qui serait sorti est quelque part autour du 149496620e terme (qui a été calculé via des flottants, donc la valeur peut ne pas être exacte).

Justin
la source

Réponses:

3

Perl, 69 octets

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

Prend les entrées comme arguments de ligne de commande.

Explication : bigratactive les fractions partout pour des calculs précis. $sest la somme actuelle des termes, $ARGV[0]est la valeur cible, pop(identique à $ARGV[1]) représente le nombre de termes $pet $nreprésente le nombre de termes positifs et négatifs. $_est soit 1ou 0selon qu'un terme positif ou négatif a été ajouté.

svsd
la source
3

Haskell, 92 91 90 octets

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

Exemple d'utilisation: 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].

hconstruit le modèle de bits infinis en portant quatre paramètres autour: aest la somme actuelle. pest le dénominateur du prochain terme positif, qpour les termes négatifs. zest le nombre cible. fdémarre tout et tronque le résultat à la longueur n.

Edit: @Zgarb a trouvé un octet à enregistrer. Merci!

nimi
la source
Définir h a p qau lieu d' h p q aenregistrer un octet.
Zgarb
Il convient de noter que 7 octets sont dépensés pour simplement couper la liste de résultats infinie à l'une de longueur n . Il serait en fait beaucoup plus agréable de simplement donner la liste infinie comme résultat.
cessé de tourner dans
1

Python 3, 128 124 octets

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)

Cela utilise la Fractionclasse 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
la source
1
'x'*int(input())?
FryAmTheEggman