Гольф последовательность, экспоненциальная производящая функция которой является касательной


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

Testcases

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
(Не могу устоять): в буквальном смысле ваше первое предложение крайне ложно!
Камбала

У вас есть смысл «порождающая функция» и «экспоненциальная порождающая функция» в обратном направлении. $ \ sin (x) $ - экспоненциальная производящая функция последовательности 0,1,0, -1,0,1,0, -1,0, ... - это не последовательность, которая является экспоненциальной производящей функцией $ \ sin (x) $. Вы просите нас кодировать последовательность, экспоненциально сгенерированную $ \ tan (x) $.
Глен О

Выглядит хорошо, за исключением того, что «Это также называется порождающей функцией этой функции. Коэффициенты n-го члена образуют последовательность.», Что, вероятно, должно говорить что-то вроде «Коэффициенты n-го члена образуют последовательность, и соответствующая функция называется «генерирующей функцией последовательности».
Глен О

@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.
Деннис

@ Денис, спасибо. Однако оказывается, что 0в любом случае это должен быть особый случай, потому что он оценивается как 1.
Питер Тейлор

1
Можно было бы подумать, что вы отвечаете не на тот вопрос, если даже не нажали на мои ссылки.
Утренняя монахиня

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

2
@ LeakyNun, так что это будет всем тогда. Я видел этот список ссылок и т. Д.
Питер Тейлор

7

Юлия, 40 38 32 байта

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

Вход и выход в форме BigFloatс. Попробуйте онлайн!

Фон

Ряд Маклаурина касательной функции удовлетворяет тождеству

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

Поскольку B 2 (n + 1) и (-1) n имеют один и тот же знак, B 2n + 1 = 0, если n> 0 и B 1 = 1/2 , мы можем переписать вышеизложенное следующим образом.

Кроме того, всякий раз, когда n является неотрицательным целым числом, мы имеем

где ζ обозначает дзета-функцию Римана .

Отсюда из соглашения 0 0 = 1 следует, что

это формула, которую использует реализация.


6

Python, 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)

Мы можем вычислить ith-й коэффициент экспоненциальной производящей функции, дифференцируя времена касательной функции iи вычисляя при 0. Каждая производная является полиномом от tan(x), а ее значение в 0 является ее постоянным членом.

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

Таким образом, производная от tan(x)**jIS

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

Mathematica, 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)^jIS

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 ответ Питера Тейлора , это вычисляет п - й член Эйлера вверх / вниз последовательность , если п нечетно и специальные футляры даже н а 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.

3

Sage, 26 байт

lambda n:tan(x).diff(n)(0)

Как и другие решения в математически ориентированных языках, эта функция вычисляет nпроизводную th tan(x)и оценивает ее в x = 0.

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


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]должно сработать.
Деннис

@ Денис - хороший улов. Не понимал, 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.