指数生成関数がタンジェントであるシーケンスをゴルフ


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-th項の係数はシーケンスを形成します。

多くの場合、n-th項にはの分母があり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 -thの用語は異なります)

実装例

# 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
関数の生成と数学での使用、特に組み合わせ論と数論の詳細を知りたい場合は、H。Wilf によるこの「有名な」教科書生成関数をお勧めします。
-flawr

5
(抵抗できません):文字通り、最初の文は非常に間違っています!
ヒラメ

「生成関数」と「指数生成関数」という意味が逆になります。$ \ sin(x)$は、シーケンス0,1,0、-1,0,1,0、-1,0、...の指数生成関数です-指数生成関数であるのはシーケンスではありません$ \ sin(x)$の。あなたが私たちに求めているのは、$ \ tan(x)$によって指数関数的に生成されたシーケンスをコーディングすることです。
グレンO

「これは、その関数の生成関数とも呼ばれます。n番目の項の係数はシーケンスを形成します。」と思われますが、「n番目の項の係数はシーケンスを形成し、対応する関数は、シーケンスの生成関数と呼ばれます」。
グレン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バイトのDennisに感謝します。

解剖

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、だからそれはみんなだろう。リンクとtl; drのリストを見ました。
ピーターテイラー

7

ジュリア、40 38 32バイト

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

入力と出力はBigFloatsの形式です。オンラインでお試しください!

バックグラウンド

接線関数のマクラウリン級数は恒等式を満たします

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)

iタンジェント関数のi時間を微分し、で評価することにより、指数生成関数のth係数を計算でき0ます。各導関数はの多項式でありtan(x)、0での値は定数項です。

の係数を再帰的に表現します tan(x)**jiの目誘導体tan機能を有しますf(i,j)。再帰式はリレーションから得られtan(x)' = 1 + tan(x)**2ます。

したがって、の導関数tan(x)**j

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

だから、への貢献者tan(x)**ji番目の誘導体でありますtan(x)**(j-1)tan(x)**(j+1)における(i-1)係数のそれぞれは、そのパワーに等しい、ST誘導体。これは再帰式を与えます

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で行われ、デフォルト値として設定されます。


これは、CJamで20バイトに移植されます。私がそれを私の主要な答えにするかどうか、それを移植して投稿したいですか?
ピーターテイラー

あなたはそれを投稿すべきです、私はCJamを知りません。
xnor

4

Mathematica、20バイト

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

簡単なアプローチ。tan(x)n 番目の導関数を計算し、で評価します x = 0ます

使用法

例


3

Haskell、48バイト

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

iタンジェント関数のi時間を微分し、で評価することにより、指数生成関数のth係数を計算でき0ます。各導関数はの多項式でありtan(x)、0の値は定数項です。

我々は、再帰の係数を表現tan(x)^jiの目誘導体tan機能を有しますi%j。再帰式はリレーションから得られtan(x)' = 1 + tan(x)^2ます。

したがって、の導関数tan(x)^j

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

だから、への貢献者tan(x)^ji番目誘導体であるtan(x)^(j-1)tan(x)^(j+1)における(i-1)係数のそれぞれは、そのパワーに等しい、ST誘導体。


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.

3

セージ、26バイト

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

数学指向言語の他のソリューションと同様に、この関数はのnth導関数を計算し、tan(x)で評価しx = 0ます。

オンラインで試す


2

J、15 13バイト

tan(x)の指数生成関数のn 番目の係数t:を計算する組み込み関数もあります。

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

@ Leaky Nunに感謝Jのテイラー級数副詞を思い出させてくれたます。

15バイトの代替。

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

別のアプローチは、tan(x)n 番目の導関数を計算し、x = 0で評価することですです。

注:で Jでは、nが10をd.超えると、微分関数によって使用されるメモリの量が急速に増加します。

使用法

   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)、適切な値を持つ行列の単純な行列の累乗を使用して、展開を生成し、2番目の行または列(構築に応じて)tan(xの導関数を保持する)自体。

したがって、結果の式で定数を見つける必要があり、それが対応する行または列の最初の値です。


!n=(spdiagm((0:n,1:n+1),(1,-1))^n)[2]動作するはずです。
デニス

@デニス-すてきなキャッチ。spdiagmその構造のスタイルを許可することに気づかなかった-で試してみましたdiagmが、もちろんうまくいきませんでした。
グレンO

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

Symbolic Toolboxを備えた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])

残念ながら、これnInt値を使用するため、適度な値の場合にオーバーフローします。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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.