Найти касательную к сумме обратных касательных

16

Фон

Можно показать , что для любого целого числа k >= 0, f(k) = tan(atan(0) + atan(1) + atan(2) + ... + atan(k))является рациональным числом.

Цель

Напишите полную программу или функцию, которая при получении k >= 0выводитf(k) как одну уменьшенную дробь (числитель и знаменатель взаимно просты).

Контрольные примеры

Первые несколько значений

f(0) = (0,1)
f(1) = (1,1)
f(2) = (-3,1)
f(3) = (0,1)
f(4) = (4,1)
f(5) = (-9,19)
f(6) = (105,73)

правила

  • Стандартные лазейки запрещены.
  • Вход и выход могут быть в любом удобном формате. Вы можете вывести f(k)как строку numerator/denominator, как кортеж из двух целых чисел, дроби или рационального объекта и т. Д. Если вы выводите строку, дайте только два целых числа, то есть выведите 3/2вместо 1 1/2.
  • Это код-гольф, самый короткий ответ (в байтах) выигрывает.
Итан Уорд
источник
1
Можете ли вы дополнительно указать в ваших тестовых примерах, каковы значения ввода / вывода?
Ян Х.
1
Находятся ли целые числа в диапазоне в градусах или радианах?
Эрик Outgolfer
1
OEIS: A180657
Сизиф
4
atan(0)Срок не является необходимым.
Адам
3
@ pizzapants184 f (0) = tan∑∅ = tan 0 = 0
17

Ответы:

11

Mathematica, 28 байт

Fold[+##/(1-##)&,0,Range@#]&

Попробуйте онлайн!

Более длинный, но более интересный подход (32 байта):

Im@#/Re@#&@Product[1+n I,{n,#}]&

Попробуйте онлайн!

alephalpha
источник
+1 o'_'oMathematica и его встроенные модулиo'_'o
Mr. Xcoder
3
@ Mr.Xcoder Не совсем в этом случае. ОП ловко использует суммирование рядов (если я правильно прочитал код).
Адам
11

Python 2 ,76 72 байта

from fractions import*
f=lambda k:Fraction(k and(k+f(k-1))/(1-k*f(k-1)))

Используйте личность:

tan(A + B) = (tan(A) + tan(B)) / (1 - tan(A) * tan(B))

У нас есть:

f(k) = 0                                    if k = 0
     = (k + f(k - 1)) / (1 - k * f(k - 1))  if k > 0

Попробуйте онлайн!

Благодаря Луису Мендо, сэкономьте 4 байта.

ТТГ
источник
1
Надеюсь, вы не возражаете: я добавил ссылку TiO.
Мистер Xcoder
@LuisMendo LGTM, Отредактировано.
17
3

APL (Dyalog) , 14 байтов

Требуется ⎕FR←1287( 128- битная F -точка позиционирования R ) для небольшого ввода. Принимает в kкачестве правильного аргумента.

1(∧÷,)3○¯3+.○⍳

Попробуйте онлайн!

 целые числа от одного до kнуля (ноль не требуется, так как 0 = arctan 0)

¯3+.○ сумма арктических касательных

3○ касательный

1() Применить следующую молчаливую функцию с 1 в качестве левого аргумента и выше, как правый аргумент:

 наименьший общий множитель (1 и правильный аргумент); дает числитель

÷ деленное на

, конкатенация (из 1 и правильный аргумент); дает числитель и знаменатель

Адам
источник
2

Haskell , 52 байта

Это использует расширение серии OEIS:

import Data.Ratio
f 0=0%1
f n|p<-f$n-1=(p+n)/(1-n*p)

Попробуйте онлайн!

Или точечная версия:

(scanl1(\f n->(f+n)/(1-n*f))[0%1..]!!)
ბიმო
источник
2

JavaScript (ES6), 80 байт

f=n=>n?([a,b]=f(n-1),g=(a,b)=>a?g(b%a,a):b,c=g(d=b*n+a,e=b-n*a),[d/c,e/c]):[0,1]

Возвращает пару [числитель, знаменатель]. Пояснение: давай f(n-1) = a/bтогда f(n) = atan(tan(n)+tan(a/b)) = (n+a/b)/(1-n*a/b) = (b*n+a)/(b-n*a). Затем остается уменьшить долю до ее самых низких сроков.

Онлайн среда ES6

Нил
источник
1

05AB1E , 33 26 байт

0X)Iƒ©`N*+®`sN*-‚D¿D_i\¤}/

Попробуйте онлайн!

объяснение

0X)                          # initialize stack with [0,1]
   Iƒ                        # for N in range [0 ... input] do:
     ©                       # store a copy of the current pair in the register
      `                      # push the pair separately to the stack
       N*                    # multiply the denominator with N
         +                   # add the numerator
          ®`s                # push the denominator then the numerator to the stack
             N*              # multiply the numerator by N
               -             # subtract it from the denominator
                D¿D          # get 2 copies of the greatest common divisor
                   0Qi  }    # if the gcd equals 0
                      \¤     # replace it with the denominator
                         /   # divide the pair with this number
Emigna
источник
1

Casio-Basic, 35 байт

tExpand(tan(sum(seq(tan⁻¹(n),n,0,k

tan -1 должен быть введен как на клавиатуре Trig; или -1 можно ввести отдельно от клавиатуры abc> Math. Согласно инструкции к fx-CP400, это один двухбайтовый символ (764).

Функция, 34 байта для кода, +1 байт для добавления kв качестве аргумента.

объяснение

seq(tan-1(n),n,0,k)генерирует все значения tan-1(n)от 0 до k.

sumскладывает их все вместе, затем tanвыполняет касательную функцию к ним.

tExpand затем превратит их в одну дробь.

numbermaniac
источник
@ Adám Это Casio, а не TI, так что это не так.
Числовой маньяк
Согласно Википедии , и ¹два байта каждый; E5CCи E5C1.
Адам
@ Adám о, я не поняла, что эта статья существует! Тем не менее, это FX-CP400, а не 9860G; Я только что проверил руководство, и верхний индекс -1 на самом деле является одним символом, код 764; так что это один двухбайтовый символ.
Числовой маньяк
0

Юлия 0.6.0 40 байт

k->rationalize(tan(sum(x->atan(x),1:k)))

Это прямая реализация вопроса. Точность рационализации иногда может быть странной, но работает хорошо в 99% случаев.

Goysa
источник