输出第n个响铃号码


13

贝尔数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]}

多种计算贝尔编号的方法,您可以自由使用其中任何一种。这里将描述一种方法:

计算贝尔数的最简单方法是对二项式系数使用类似于Pascal三角形的数字三角形。钟形数字出现在三角形的边缘。从1开始,通过将上一行的最后一个条目作为第一个条目,然后将每个新条目设置为其左邻居加上左上邻居,来构造三角形中的每个新行:

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

您可以使用0索引或1索引。如果使用0索引,则输入3应该为输出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索引,则输入的3输出应为5 ouput 15,对吗?并使用1索引将输出5
Luis Mendo

其背后的原因是将第0个响铃编号计数为0索引中的索引0和1索引中的索引1。您的方法可能会更清楚,但是现有的答案可以这样工作,因此我现在无法更改。我刚刚加入这个网站在几个小时前
操纵

但是您说使用1索引时,input 3应该输出2。那么输入将为11-indexing提供什么呢?
路易斯·门多

1-> 1,2-> 1,3-> 2(对应于0、1、2钟号码),而不是0-> 1,1-> 1,2-> 2也许我使用的是错误的术语
操纵

我想我明白了。示例表和输出中缺少前一个,这使我感到困惑
Luis Mendo

Answers:


2

果冻,9字节

ṖµṀcæ.߀‘

这使用公式

式

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索引,第二个是1索引。




4

Mathematica,24个字节

Sum[k^#/k!,{k,0,∞}]/E&

@Kelly Lowder的-13个字节!


Sum[k^#/k!,{k,0,∞}]/E&只有24个字节
Kelly Lowder

3

果冻14 12 11字节

ṫ0;⁸+\
1Ç¡Ḣ

在线尝试!

并没有动态地输入¡ Jelly的强项总是修改数组并且缺少前置原子(一个字节;@或反向)。


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开始。在线尝试!

说明

这使用公式

在此处输入图片说明

其中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个Bell数。


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

在线尝试!

B(n)计算为第二种斯特林数的总和。


那是一个很好的解决方案。请注意,如果使用第二种斯特林数字内置函数,则可以计算贝尔数(如果使用Mathematica或类似方法)
操纵

您可以在的定义中直接保存两个字节s:由于递归调用始终会减少n,因此在第一个术语中除以除法不会k丢失*k
彼得·泰勒

或者,您可以将其展平为一个lambda来处理一整行,从而节省一堆: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)
Peter Taylor

由于您的函数B不是递归的,并且是您的最终答案,因此可以省略B=节省2个字节
Felipe Nardi Batista

2

MATLAB,128103字节

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中使用。

这使用递归lambda构造高尔夫球循环来建立Aitken三角形。



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中68 60个字节

三角形的简单递归构造,但在实际应用中效率很低。计算最多15个贝尔号会导致TIO超时,但它在我的机器上有效。

这使用1索引,并返回True而不是1。

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

在线尝试!


感谢@FelipeNardiBatista节省了8个字节!


60个字节。返回布尔值而不是数字(0,1)在python中是可接受的
Felipe Nardi Batista

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索引

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

说明

这是程序的标准模板,这些程序在顺序模式下输入,在基本模式下进行处理,然后在顺序模式下输出结果。1已将A 添加到模板中,以将该值放在输入下方的堆栈中。

该程序使用堆栈作为扩展的圆形队列来计算三角形的每一行。在经过第一个迭代的每次迭代期间,堆栈下方的一个隐式零将变为显式零。

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,但第一次迭代有效地假定初始堆栈深度为零。结果,1最终被加到自己身上,并且整个三角形乘以2。将最终结果除以2得到正确的答案。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.