n番目のベル番号を出力する


13

A ベル番号OEIS A000110は)N標識された(別個の)要素のセットを分割する方法の数です。0番目のベル番号は1として定義されます。

いくつかの例を見てみましょう(パーティションのサブセットとブレースを示すために括弧を使用します):

1: {1}
2: {[1,2]}, {[1],[2]}
3: {[1,2,3]}, {[1,2],[3]}, {[1,3],[2]}, {[2,3],[1]}, {[1],[2],[3]}

ベル番号を計算するには多くの方法があり、自由に使用できます。1つの方法をここで説明します。

ベル数を計算する最も簡単な方法は、二項係数にパスカルの三角形に似た数三角形を使用することです。ベル番号は、三角形の端に表示されます。1から開始して、三角形の各新しい行は、前の行の最後のエントリを最初のエントリとして、左の隣人と左上の隣人にそれぞれの新しいエントリを設定することによって構築されます。

1
1    2
2    3    5
5    7   10   15
15  20   27   37   52

0インデックスまたは1インデックスを使用できます。0インデックスを使用する場合、入力は3output 5である必要がありますが2、1インデックスを使用する場合は出力する必要があります。

プログラムは、15番目のベル番号まで動作し、を出力する必要があり1382958545ます。理論的には、プログラムはより大きな数を処理できる必要があります(つまり、ソリューションをハードコーディングしないでください)。 編集:三角法によって計算されないため、0(0インデックス付けの場合)または1(1インデックス付けの場合)の入力を処理する必要はありません。

テストケース(0インデックス付けを想定):

0 ->  1 (OPTIONAL)
1 ->  1 
2 ->  2 
3 ->  5 
4 ->  15 
5 ->  52 
6 ->  203 
7 ->  877 
8 ->  4140 
9 ->  21147 
10 -> 115975 
11 -> 678570 
12 -> 4213597 
13 -> 27644437 
14 -> 190899322 
15 -> 1382958545

ベル番号を直接生成する組み込みの方法(Wolfram言語のBellB [n]など)を使用した回答は、非競争的です。

最短コード(バイト単位)が優先されます。


0-indexingを使用する場合、の入力は35それを出力するはず15です、そうですか?1インデックスを使用すると、出力されます5
ルイスメンドー

その背後にある理由は、0番目のベル番号を0インデックス付けでインデックス0、1インデックス付けでインデックス1としてカウントすることでした。あなたの方法はもっと明確かもしれませんが、既存の答えはそのように機能するので、私は今それを変更することはできません。数時間前にこのサイトに参加しました。
リグ

しかし、1-indexingを使用すると、入力3はoutputになります2。次に1、1インデックス付けで入力は何をしますか?
ルイスメンドー

1-> 1、2-> 1、3-> 2(0、1、2番目のベル番号に対応)0-> 1、1-> 1、2-> 2用語
リグ

わかったと思う。最初の1は私を混乱あなたの例のテーブルと出力に欠けている
ルイスMendo

回答:


2

ゼリー、9バイト

ṖµṀcæ.߀‘

これは式を使用します

formula

n <2のときはいつでも閉じられます。

オンラインでお試しください!

使い方

ṖµṀcæ.߀‘  Main link. Argument: n

Ṗ          Pop; yield A := [1, ..., n-1].
 µ         Begin a new, monadic chain with argument A.
  Ṁ        Maximum; yield n-1.
   c       Combinatons; compute (n-1)C(k) for each k in A.
      ߀   Recursively map the main link over A.
    æ.     Take the dot product of the results to both sides.
        ‘  Increment; add 1 to the result.

8

JavaScript(ES6)、47バイト

f=(n,a=[b=1])=>n--?f(n,[b,...a.map(e=>b+=e)]):b
f=(n,a=[b=1])=>--n?f(n,[b,...a.map(e=>b+=e)]):b

最初のインデックスは0で、2番目のインデックスは1です。






3

CJam(19バイト)

Xa{X\{X+:X}%+}qi*0=

オンラインデモ

解剖

Xa         e# Start with an array [1]
{          e# Repeat...
  X\       e#   Put a copy of X under the current row
  {X+:X}%  e#   Map over x in row: push (X+=x)
  +        e#   Prepend that copy of last element of the previous row to get the next row
}
qi*        e# ... input() times
0=         e# Select the first element

3

MATL、14バイト

:dtEw1Zh1Ze/Yo

入力は0ベースです。オンラインでお試しください!

説明

これは式を使用します

enter image description here

ここで、p F qa 1、...、a p ; b 1、...、b q ; x)は、一般化された超幾何関数です。

:      % Implictly input n. Push array [1 2 ... n]
d      % Consecutive differences: array [1 ... 1] (n-1 entries)
tE     % Duplicate, multiply by 2: array [2 ... 2] (n-1 entries)
w      % Swap
1      % Push 1
Zh     % Hypergeometric function
1Ze    % Push number e
/      % Divide
Yo     % Round (to prevent numerical precision issues). Implicitly display

3

Python、42バイト

f=lambda n,k=0:n<1or k*f(n-1,k)+f(n-1,k+1)

オンラインでお試しください!

再帰的な式は、n要素をパーティションに配置することから得られます。各要素について、それを配置するかどうかを決定します。

  • k選択肢がある既存のパーティションに
  • 新しいパーティションを開始し、k将来の要素の選択肢の数を増やします

どちらの方法でもn、配置する要素の残りの数が減ります。そこで、我々は、再帰的な式を持っているf(n,k)=k*f(n-1,k)+f(n-1,k+1)f(0,k)=1し、f(n,0)n番目のベル数。


2

Python 2、91バイト

s=lambda n,k:n*k and k*s(n-1,k)+s(n-1,k-1)or n==k
B=lambda n:sum(s(n,k)for k in range(n+1))

オンラインでお試しください!

第2種のスターリング数の合計として計算されたB(n)。


それは素晴らしい解決策です。第2種のスターリング数の組み込みを使用すると、ベル数の計算が許可されることに注意してください(Mathematicaなどを使用する場合)
装備

s:の定義に2バイトを直接保存できます。なぜなら再帰呼び出しは常に減少し、最初の項で失うことのできるn除算がないからkです*k
ピーターテイラー

それとも、行全体に取り組んで、1つのラムダに平坦化することにより束を保存することができます:B=lambda n,r=[1,0]:n and B(n-1,[k*r[k]+r[k-1]for k in range(len(r))]+[0])or sum(r)
ピーター・テイラー

あなたの関数のようにB再帰的ではありません、それはあなたの最終的な答えである、あなたは、省略することができますB=する2バイト保存
フェリペ・ナルディバティスタ

2

MATLAB、128 103バイト

function q(z)
r(1,1)=1;for x=2:z
r(x,1)=r(x-1,x-1);for y=2:x
r(x,y)=r(x,y-1)+r(x-1,y-1);end
end
r(z,z)

かなり自明です。行末でセミコロンを省略すると、結果が出力されます。

Luis Mendoのおかげで25バイト節約されました。




2

オーム、15バイト

2°M^┼ⁿ^!/Σ;αê/≈

オンラインでお試しください!

Dobinskiのforumlaを使用します(B(0)yayでも動作します)。

説明

2°M^┼ⁿ^!/Σ;αê/≈
2°        ;     # Push 100
  M             # Do 100 times...
   ^             # Push index of current iteration
    ┼ⁿ           # Take that to the power of the user input
      ^!         # Push index factorial
        /        # Divide
         Σ       # Sum stack together
           αê   # Push e (2.718...)
             /  # Divide
              ≈ # Round to nearest integer (Srsly why doesn't 05AB1E have this???)

2

Python(79バイト)

B=lambda n,r=[1]:n and B(n-1,[r[-1]+sum(r[:i])for i in range(len(r)+1)])or r[0]

オンラインデモPython 2のですが、Python 3でも機能します。

これにより、ゴルフループの再帰ラムダを使用してエイトケンの三角形が構築されます。



1

J、17バイト

0{]_1&({+/\@,])1:

三角形の計算方法を使用します。

オンラインでお試しください!

説明

0{]_1&({+/\@,])1:  Input: integer n
               1:  The constant 1
  ]                Identity function, get n
   _1&(       )    Call this verb with a fixed left argument of -1 n times
                   on itself starting with a right argument [1]
             ]       Get right argument
       {             Select at index -1 (the last item)
            ,        Join
        +/\@         Find the cumulative sums
0{                 Select at index 0 (the first item)

1

Python 3、78バイト

from math import*
f=lambda n:ceil(sum(k**n/e/factorial(k)for k in range(2*n)))

計算のために別のルートを試してみることにしました。これは、0でインデックス付けされたDobinskiの式を使用し、0では機能しません。

オンラインでお試しください!


1
あなたの関数のようにf再帰的ではありません、あなたは省略することができますf=し、2バイトのセーブ
フェリペ・ナルディバティスタ

1

Pythonの368 60バイト

三角形の単純な再帰的構築ですが、実際の目的には非常に非効率的です。15番目のベル番号まで計算すると、TIOはタイムアウトしますが、私のマシンでは機能します。

これは1インデックスを使用し、1のTrue代わりに戻ります。

f=lambda r,c=0:r<1or c<1and f(r-1,r-1)or f(r-1,c-1)+f(r,c-1)

オンラインでお試しください!


8バイトを節約してくれた@FelipeNardiBatistaに感謝します!


60バイト。数字(0,1)の代わりにブール値を返すことはPythonで受け入れ可能です
フェリペナルディバティスタ

1

PHP、72バイト

再帰関数1インデックス付き

function f($r,$c=0){return$r?$c?f($r-1,$c-1)+f($r,$c-1):f($r-1,$r-2):1;}

オンラインでお試しください!

PHP、86バイト

0インデックス付き

for(;$r++<$argn;)for($c=~0;++$c<$r;)$l=$t[$r][$c]=$c?$l+$t[$r-1][$c-1]:($l?:1);echo$l;

オンラインでお試しください!

PHP、89バイト

再帰関数0-indexed

function f($r,$s=NULL){$c=$s??$r-1;return$r>1?$c?f($r-1,$c-1)+f($r,$c-1):f($r-1,$r-2):1;}

オンラインでお試しください!


1

アリス、22バイト

/oi
\1@/t&wq]&w.q,+k2:

オンラインでお試しください!

これは、三角形の方法を使用します。n = 0の場合、これは代わりにB(1)を計算します。これはB(0)に便利です。

説明

これは、序数モードで入力を受け取り、それを基数モードで処理し、結果を序数モードで出力するプログラムの標準テンプレートです。A1がテンプレートに追加され、その値が入力の下のスタックに配置されます。

プログラムは、三角形の各行を計算するために、スタックを拡張循環キューとして使用します。1回目以降の各反復では、スタックの下の1つの暗黙的なゼロが明示的なゼロになります。

1     Append 1 to the implicit empty string on top of the stack
i     Get input n
t&w   Repeat outer loop that many times (push return address n-1 times)
q     Get tape position (initially zero)
]     Move right on tape
&w    On iteration k, push this return address k-1 times
      The following inner loop is run once for each entry in the next row
.     Duplicate top of stack (the last number calculated so far)
q,    Move the entry k spaces down to the top of the stack: this is the appropriate entry
      in the previous row, or (usually) an implicit zero if we're in the first column
+     Add these two numbers
k     Return to pushed address: this statement serves as the end of two loops simultaneously
2:    Divide by two: see below
o     Output as string
@     Terminate

最初の反復では、スタックの最上部に1が必要であるにもかかわらず、最初のスタックの深さは事実上0であると想定されます。その結果、1がそれ自体に追加され、三角形全体に2が乗算されます。最終結果を2で除算すると、正しい答えが得られます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.