Гольф Послідовність, Експоненціальна генеруюча функція є дотичною


15

Практично кожна функція може бути виражена як многочлен з нескінченними членами.

Наприклад, e^x = 1 + x + x^2/2! + x^3/3! + x^4/4! + ...

Наприклад, sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...

Коефіцієнти n-го доданків утворюють послідовність, і відповідна функція називається Функцією, що генерує послідовність.

Коефіцієнти n-й доданків утворюють послідовність.

Часто n-й термін має знаменник n!. Тому множимо коефіцієнт n!на отримання іншої послідовності, Експоненціальна функція генерування якої була б вихідною функцією.

Наприклад, послідовність, експоненціальною функцією генерування якої e^xбуде 1,1,1,1,....

Наприклад, послідовність, експоненціальною функцією генерування якої sin(x)буде 0,1,0,-1,0,1,0,-1,....

Завдання

Ваше завдання полягає в тому, щоб знайти n-ю член послідовності якого експоненціальна виробляє функція є tan(x).

Тестові шафи

n result
0 0
1 1
2 0
3 2
4 0
5 16
6 0
7 272
8 0
9 7936
10 0
11 353792
12 0
13 22368256
14 0
15 1903757312
16 0
17 209865342976
18 0
19 29088885112832
20 0
21 4951498053124096
22 0
23 1015423886506852352
24 0
25 246921480190207983616
26 0

(Скопійовано звідси .) (Попередження: 0-й термін інший)

Приклад реалізації

# copied from https://github.com/Mego/Seriously/blob/v2.0/SeriouslyCommands.py#L16
def memoized(f):
    memo = {}
    def m_fun(*args):
        if args in memo:
            return memo[args]
        else:
            res = f(*args)
            memo[args] = res
            return res
    return m_fun

# copied from https://github.com/Mego/Seriously/blob/v2.0/SeriouslyCommands.py#L169
@memoized
def binomial(n,r):
    if r > n:
        return 0
    elif r==n:
        return 1
    res = 1
    i = 1
    while i<=r:
        res *= (n+1-i)
        res /= i
        i+=1
    return int(res)

# 2*u(n+1) = Sum_{k=0..n} binomial(n, k)*u(k)*u(n-k)
# from A000111
@memoized
def u(n):
    if n<0: return 0
    if n==0: return 1
    if n==1: return 1
    return sum([binomial(n-1,k)*u(k)*u(n-1-k) for k in range(n)])//2     

def t(n):
    if n%2 == 0: return 0
    return u(n)

print('\n'.join([str(x) + ' ' + str(t(x)) for x in range(26)]))

Ідей це!

Список літератури


4
Якщо ви хочете дізнатися більше про генерування функцій та їх використання в математиці, особливо комбінаториці та теорії чисел, я настійно рекомендую цей «відомий» підручник, що генерує функціональну функцію Х. Вілфа.
flawr

5
(Не можу протистояти): якщо взяти буквально, ваше перше речення є надзвичайно помилковим!
Flounderer

Ви маєте значення "генеруюча функція" та "експоненціальна функція генерування" назад. $ \ sin (x) $ - експоненціальна функція генерування послідовності 0,1,0, -1,0,1,0, -1,0, ... - це не послідовність, яка є експоненціальною функцією, що генерує з $ \ sin (x) $. Що ви просите нас зробити - це кодувати послідовність, експоненціально породжену $ \ tan (x) $.
Глен О

Виглядає чудово, за винятком "Це також називається функцією, що генерує цю функцію. Коефіцієнти n-го доданків утворюють послідовність", яка, ймовірно, повинна говорити щось на кшталт "Коефіцієнти n-го доданків утворюють послідовність, і відповідна функція називається функцією, що генерує послідовність ".
Glen O

@GlenO Відредаговано.
Лина монахиня

Відповіді:


8

CJam ( 33 32 27 26 23 20 байт)

2,{ee::*_(@+.+}ri*0=

Демонстрація в Інтернеті

Розсічення

Це по суті реалізує рецидив, описаний xnor .

2,        e# [0 1] represents the base case f(0,j) = j==1
{         e# Loop...
  ee::*   e#   Multiply each array element by its index
  _(@+.+  e#   Sum the array shifted left and the array shifted right
}ri*      e# ... n times
0=        e# Evaluate at j=0

Або з досить іншим підходом, для 23 байт:

ri_1&a{{1$+}*]W%0+}@*0=

Інтернет демо . Завдяки Деннісу за 3 байти.

Розсічення

1a         e# Push [1]
{          e# Repeat...
  {1$+}*]  e#   Compute array of partial sums
  W%0+     e#   Reverse and append 0
}qi:A*     e# ... A times, where A is the input value
0=A1&*     e# Result is first element if A odd, and 0 otherwise

Або із зовсім іншим підходом, для 29 байт:

qie!Ma-{W\+W+3ew{_$.=1=},!},,

Демонстрація в Інтернеті

На жаль, для введення даних потрібен окремий випадок 0.

Розсічення

qi            e# Take an integer n from stdin
e!            e#   Compute all permutations of [0 ... n-1]
Ma-           e#   Special-case n=0
{             e#   Filter...
  W\+W+       e#     Prepend and postpend -1
  3ew         e#     Take slices of 3 consecutive elements
  {           e#     Filter...
    _$.=1=    e#       Test whether the middle element is the second largest
  },!         e#     ... and require no matches
},,           e#   ... and count

Ви можете думати: "WTF ?! Він відповідає на неправильне запитання". Якщо це так, це зрозуміло, але обидва підходи дійсно дають правильні результати .


У випадку, якщо ot допоможе, щомісячне нарощування на TIO повертає порожній масив для [WW]3ew.
Денніс

@Dennis, спасибі Однак, виявляється, це 0все одно має бути окремим випадком, оскільки він оцінює 1.
Пітер Тейлор

1
Можна було б подумати, що ти відповідаєш на неправильне запитання, якщо навіть не натиснув на мої посилання.
Leaky Nun

ri_1&a{{1$+}*]W%0+}@*0=економить 3 байти.
Денніс

2
@LeakyNun, так що тоді були б усі. Я побачив цей список посилань і tl; dr.
Пітер Тейлор

7

Джулія, 40 38 32 байт

!n=2(2*4^n-2^n-0^n)abs(zeta(-n))

Введення та вихід у формі BigFloats. Спробуйте в Інтернеті!

Фон

Серія Маклауріна дотичної функції задовольняє тотожність

всякий раз, коли х лежить у радіусі його зближення, де B n - це число Бернуллі.

Оскільки B 2 (n + 1) і (-1) n мають однаковий знак, B 2n + 1 = 0, якщо n> 0 і B 1 = 1/2 , ми можемо переписати вищенаведене наступним чином.

Крім того, коли n є невід’ємним цілим числом, ми маємо

де ζ позначає зета-функцію Рімана .

З цього з умовою 0 0 = 1 випливає, що

що є формулою, яку використовує реалізація.


6

Пітон, 57 байт

f=lambda i,j=0:~-j*f(i-1,j-1)-~j*f(i-1,j+1)if i else j==1

Менше гольфу:

f=lambda i,j=0:j==1 if i==0 else (j-1)*f(i-1,j-1)+(j+1)*f(i-1,j+1)

Ми можемо обчислити iкоефіцієнт th функції експоненціальної генерації, диференціюючи дотичну функціюi часу і оцінивши при 0. Кожна похідна є многочленом у tan(x), а її значення при 0 - її постійний час.

Рекурсивно виражаємо коефіцієнт tan(x)**jв- iй похідноїtan з функцією f(i,j). Рекурсивний вираз походить від відношення tan(x)' = 1 + tan(x)**2.

Отже, похідне від tan(x)**j IS

j*tan(x)**(j-1)*(tan(x)**2+1), or equivalently
j*tan(x)**(j+1) + j*tan(x)**(j-1)

Отже, дописувачами tan(x)**jу- iй похідної є tan(x)**(j-1)і tan(x)**(j+1)в(i-1) похідній я, кожен з яких має коефіцієнт , що дорівнює її потужність. Це дає рекурсивний вираз

f(i,j) = (j-1)*f(i-1,j-1) + (j+1)*f(i-1,j+1)

Зауважте, що нам не потрібно виключати негативні показники, jоскільки вони так чи інакше оцінюють нуль і не вносять внесок через перехрестяj=0 дає множник 0.

Базовий випадок i==0відповідає tan(x)самому собі j==1, а нульовим коефіцієнтам інакше. Остаточне оцінювання відбувається в постійний термін j=0, який вводиться як значення за замовчуванням.


Це порти на 20 байт у CJam. Чи не заперечуєте ви, якщо я зробив це своїм основним варіантом відповіді, чи ви хочете передати його та опублікувати?
Пітер Тейлор

Ви повинні опублікувати це, я не знаю CJam.
xnor

4

Математика, 20 байт

Tan@x~D~{x,#}/.x->0&

Прямий підхід. Обчисліть n - похідну від tan (x) та оцініть її при x = 0 .

Використання

Приклад


3

Haskell, 48 байт

0%1=1
0%_=0
i%j=sum[k*(i-1)%k|k<-[j+1,j-1]]
(%0)

Ми можемо обчислити iкоефіцієнт th функції експоненціальної генерації, диференціювавши дотичні функції iчасу і оцінивши при 0. Кожна похідна є многочленом у tan(x), а значення при 0 - її постійний час.

Рекурсивно виражаємо коефіцієнт tan(x)^jв- iй похідної функціїtan з функцією i%j. Рекурсивний вираз походить від відношення tan(x)' = 1 + tan(x)^2.

Таким чином, похідна відtan(x)^j IS

j*tan(x)^(j-1)*(tan(x)^2+1), or equivalently
j*tan(x)^(j+1) + j*tan(x)^(j-1)

Таким чином, внесок в tan(x)^jв iе похідною є tan(x)^(j-1)і tan(x)^(j+1)в (i-1)похідній я, кожен з яких має коефіцієнт , що дорівнює її потужність.


3

Желе , 12 11 байт

Ṛ+\;S
ḂÇ⁸¡Ḣ

Як і відповідь Пітера Тейлора на CJam , це обчислює n- й термін послідовності вгору / вниз Ейлера, якщо n є непарним, а особливі випадки - навіть n як 0 .

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

ḂÇ⁸¡Ḣ  Main link. Argument: n

Ḃ       Bit; yield n's parity.
 Ç⁸¡    Apply the helper link (Ç) n (⁸) times.
    Ḣ   Head; retrieve the first element of the resulting list.


Ṛ+\;S   Helper link. Argument: A (list or 1/0)

Ṛ       Cast A to list (if necessary) and reverse the result.
 +\     Take the cumulative sum.
   ;S   Append the sum of A.


2

J, 15 13 байт

Існує також вбудований, t:який обчислює n- й коефіцієнт експоненціальної функції породження tan (x) .

(1&o.%2&o.)t:

Завдяки @ Leaky Nun за те, що він нагадав мені про прислівники серії Тейлор у J, які зберегли 2 байти.

Альтернатива на 15 байт .

3 :'(3&o.d.y)0'

Інший підхід полягає в обчисленні n- ї похідної tan (x) і оцінці її при x = 0 .

Примітка: У J об'єм пам'яті, використовуваної похідною функцією, d.швидко зростає, коли n проходить 10.

Використання

   f =: (1&o.%2&o.)t:
   f 7
272
   (,.f"0) i. 11  NB. Additional commands are just for formatting the output
 0    0
 1    1
 2    0
 3    2
 4    0
 5   16
 6    0
 7  272
 8    0
 9 7936
10    0

Пояснення

(1&o.%2&o.)t:  Input: n
(         )    Define a monad (one argument function), call the input y
 1&o.          Get the trig function sin(x) and call it on y
      2&o.     Get the trig function cos(x) and call it on y
     %         Divide sin(y) by cos(y) to get tan(y)
           t:  Get the nth coefficient of the exponential generating series
               for that function and return

3 :'(3&o.d.y)0'  Input: n
3 :'          '  Define a monad (one argument function) with input y
     3&o.        Get the trig function tan(x)
           y     The input n
         d.      Get the nth derivative of tan(x)
             0   Evaluate the nth derivative at x = 0 and return

2

Джулія, 39 37 байт

!n=(spdiagm((0:n,1:n+1),(1,-1))^n)[2]

Збережено 2 байти завдяки Деннісу.

Не найкоротше рішення Джулії (див. Рішення Денніса), але це робиться виключно з використанням похідної логіки ... у вигляді матриць.

В основному, він використовує той факт, що похідна tan (x) дорівнює 1 + tan (x) ^ 2. Отже, оскільки похідна будь-якої сили tan (x), скажімо, tan (x) ^ k, є k tan (x) ^ (k-1) tan (x) '= k tan (x) ^ (k-1) + k tan (x) ^ (k + 1), ми можемо використовувати просту потужність матриці на матриці з відповідними значеннями для генерації розширення, при цьому другий рядок або стовпець (залежно від побудови) утримує похідні tan (x ) себе.

Тому нам просто потрібно знайти константу в отриманому виразі, і це перше значення у відповідному рядку чи стовпці.


!n=(spdiagm((0:n,1:n+1),(1,-1))^n)[2]повинні працювати.
Денніс

@Dennis - приємний улов. Не розумів, spdiagmщо дозволить такий стиль будівництва - спробував це diagm, але, звичайно, не вийшло.
Глен О

2

JavaScript (ES6), 127 45 байт

f=(n,m=0)=>n?++m*f(--n,m--)+--m*f(n,m):m-1?0:1

Порт рішень @ xnor.


0

Haskell, 95 93 байт

p=product
f n=sum[(-1)^(n`div`2+j+1)*j^n*p[k-j+1..n+1]`div`p[1..n+1-k+j]|k<-[1..n],j<-[0..k]]

Це в основному реалізація загальної формули з деякими незначними оптимізаціями.


0

MATLAB з символічною панеллю інструментів, 84 байти

n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)

Приклад виконання:

>> n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)
7
ans =
272

>> n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)
8
ans =
0

>> n=input('');syms x;c=coeffs(taylor(tan(x),'Order',n+1))*factorial(n);c(end)*mod(n,2)
9
ans =
7936

0

Haskell (занадто багато байтів)

Використовуючи тільки операції за списками і Раймонда Мандзоні результат :

c n = last $ map numerator $ zipWith (*) (scanl (*) (1) [2,3..]) (intersperse 0 $ foldr (.) id (replicate n (\xs->(xs ++ [(1%(1+2*length xs)) * (sum (zipWith (*) xs (reverse xs)))]))) [1])

На жаль, це переповнює скромні значення n, оскільки використовує Intзначення. Я спробую виправити проблему за допомогою Integerзначень. До цього часу пропозиції вітаються.


0

Аксіома, 46 байт

f(n:NNI):NNI==(n=0=>0;eval(D(tan(x),x,n),x=0))

код для тестування та результатів

(32) -> [[i, f(i)] for i in 0..26]
   (32)
   [[0,0], [1,1], [2,0], [3,2], [4,0], [5,16], [6,0], [7,272], [8,0], [9,7936],
    [10,0], [11,353792], [12,0], [13,22368256], [14,0], [15,1903757312],
    [16,0], [17,209865342976], [18,0], [19,29088885112832], [20,0],
    [21,4951498053124096], [22,0], [23,1015423886506852352], [24,0],
    [25,246921480190207983616], [26,0]]
                                       Type: List List NonNegativeInteger
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.