Гармоничная «конвергенция»


16

Серия чередующихся гармоник - хорошо известная сходящаяся серия.

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

«Понятно», очевидно, что оно сходится к натуральному логарифму 2. Или так?

Поскольку ряд не является абсолютно сходящимся , просто переставляя термины, я могу сделать так, чтобы он подходил ко всему, что я хочу. Предположим, я хочу, чтобы ряд сходился к e . Все, что мне нужно сделать, это:

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

Если вы не уловили шаблон, не существует очевидного. Вот как это работает:

  1. Рассмотрим члены ряда чередующихся гармоник в терминах положительных и отрицательных членов.
  2. Добавьте вместе достаточно положительных условий, чтобы превзойти нашу цель (е). (иначе sum > target)
  3. Вычтите следующий отрицательный член.
  4. Вернитесь к 2.

Обратите внимание, что на шаге 2, если наш sum == target, вы должны добавить еще один положительный термин.

Из этого мы можем определить последовательность, связанную с каждым числом следующим образом:

  • Следуйте алгоритму выше
  • Для каждого положительного члена выведите 1.
  • Для каждого отрицательного члена выведите 0.

Давайте назовем эту последовательность «Гармоничным битовым шаблоном» числа. Например, HBP e начинается как:

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

Ваша задача:

Вам будет предоставлено:

  • рациональная входная цель в диапазоне [-10, 10] (примечание: даже достижение 10 через ряд гармоник занимает много миллионов терминов). Это может быть десятичная дробь (ака 1.1) или вы можете принять рациональное напрямую (ака 12/100)
  • положительный int n- вход, определяющий количество членов гармонического битового шаблона для вывода.

Ожидается, что вы выведите точный гармонический битовый паттерн цели с указанным количеством терминов. Вы можете выводить разделенные пробелами значения, разделенные запятыми, без разделения и т.д .; до тех пор, пока последовательность 0 и 1 ясно видна и читается слева направо с постоянным разделением.

Тестовые случаи

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

Обратите внимание, что, поскольку -9.8он настолько велик, первое, 1что будет выведено, находится где-то вокруг 149496620th-го члена (который был вычислен с помощью чисел с плавающей запятой, поэтому значение может быть не точным).

Ответы:


3

Perl, 69 байт

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

Принимает входные данные в качестве аргументов командной строки.

Пояснение : bigratпозволяет использовать дроби везде для точных расчетов. $sявляется текущей суммой терминов, $ARGV[0]является целевым значением pop(так же, как $ARGV[1]) представляет количество терминов $pи $nпредставляет положительное и отрицательное число терминов. $_либо 1или в 0зависимости от того, был добавлен положительный или отрицательный термин.


3

Haskell, 92 91 90 байт

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

Пример использования: 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].

hсоздает бесконечную битовую комбинацию путем переноса четырех параметров: aтекущая сумма. pявляется знаменателем следующего положительного члена, qдля отрицательных. zэто номер цели. fзапускает все и обрезает результат до длиныn .

Изменить: @Zgarb нашел байт для сохранения. Благодарность!


Определение h a p qвместо h p q aсохранения байта.
Згарб

Следует отметить, что 7 байтов расходуются только на обрезание бесконечного списка результатов до длины n . На самом деле было бы гораздо приятнее просто привести бесконечный список в качестве результата.
перестал поворачиваться против часовой стрелки с

1

Python 3, 128 124 байта

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)

Это использует Fractionкласс 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.