“Convergenza” armoniosa


16

La serie armonica alternata è una serie convergente ben nota.

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

"Chiaramente", è ovvio che converge nel registro naturale di 2. O lo fa?

Poiché la serie non è assolutamente convergente , semplicemente riorganizzando i termini, posso farla avvicinare a tutto ciò che voglio. Supponiamo che io voglia che le serie convergano in e . Tutto ciò che dovrei fare è questo:

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

Se non hai colto lo schema, non ce n'è uno ovvio. Ecco come funziona:

  1. Considera i termini delle serie armoniche alternate in termini di termini positivi e negativi.
  2. Aggiungi solo abbastanza termini positivi per superare il nostro obiettivo (e). (aka sum > target)
  3. Sottrai il prossimo termine negativo.
  4. Torna a 2.

Si noti che al passaggio 2, se nostro sum == target, è necessario aggiungere un altro termine positivo.

Da questo possiamo definire una sequenza associata a ciascun numero come segue:

  • Segui l'algoritmo sopra
  • Per ogni termine positivo, uscita 1.
  • Per ogni termine negativo, output 0.

Chiamiamo questa sequenza "Harmonious Bit Pattern" di un numero. Ad esempio, l'HBP di e inizia come:

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

La tua sfida:

Ti verrà dato:

  • un target di input razionale nell'intervallo [-10, 10] (nota: anche il raggiungimento di 10 tramite la serie armonica richiede molti milioni di termini). Questo può essere un decimale (aka 1.1) o puoi prendere direttamente un razionale (aka 12/100)
  • un input positivo int n , che specifica il numero di termini del modello di bit armonioso da emettere.

Ci si aspetta che l'output del modello di bit armonioso esatto del target esista al numero specificato di termini. È possibile generare valori separati da spazio, separati da virgola, nessuna separazione, ecc .; fintanto che il modello di 0 e 1 è chiaramente visibile e viene letto da sinistra a destra con una separazione coerente.

Casi 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

Si noti che poiché -9.8è così grande, il primo 1che verrebbe prodotto è da qualche parte attorno al 149496620termine (che è stato calcolato tramite float, quindi il valore potrebbe non essere esatto).

Risposte:


3

Perl, 69 byte

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

Accetta input come argomenti della riga di comando.

Spiegazione : bigratabilita le frazioni ovunque per calcoli accurati. $sè la somma attuale dei termini, $ARGV[0]è il valore target pop(uguale a $ARGV[1]) rappresenta il numero di termini $pe $nrappresenta i conteggi dei termini positivi e negativi. $_è 1o a 0seconda che sia stato aggiunto un termine positivo o negativo.


3

Haskell, 92 91 90 byte

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

Esempio di utilizzo: 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].

hcostruisce il modello di bit infinito portando in giro quattro parametri: aè la somma corrente. pè il denominatore del prossimo termine positivo, qper termini negativi. zè il numero di destinazione. favvia tutto e tronca il risultato in lunghezza n.

Modifica: @Zgarb ha trovato un byte da salvare. Grazie!


Definire h a p qinvece di h p q asalvare un byte.
Zgarb,

Va notato che 7 byte vengono spesi solo per tagliare l'elenco dei risultati infiniti su uno di lunghezza n . In realtà sarebbe molto più bello dare semplicemente l'elenco infinito come risultato.
cessò di girare in senso antiorario il

1

Python 3, 128 124 byte

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)

Questo fa uso della Fractionclasse di 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.

1
'x'*int(input())?
FryAmTheEggman,
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.