莫兹金数


30

第n个Motzkin数是从(0,0)到(n,0)的路径数,其中每个步骤的形式为(1,-1),(1,0)或(1,1),以及路径永远不会低于y = 0。

这是上述链接中n = 1、2、3、4的这些路径的说明:

莫兹金数

所需序列为OEIS A001006。OEIS具有该序列的其他一些特征。


您将得到一个正整数n作为输入。您应该输出第n个Motzkin编号。

以下是莫兹金数1到10:

1, 2, 4, 9, 21, 51, 127, 323, 835, 2188

允许所有标准输入和输出方法。有标准漏洞

这是代码高尔夫。最少的字节数获胜。


我们必须能够生成的最小的莫兹金数集是什么?
艾迪生·克伦普


@FlagAsSpam所有这些,不受时间/内存/数据类型的限制。
isaacg 2015年

我认为语言现在需要内置的Dyck单词。
lirtosiast

Answers:


15

MATL,13 14字节

i-2/t.5+hH4Zh

例:

>> matl i-2/t.5+hH4Zh
> 6
51

编辑(2017年6月16日):您可以在线尝试!还要注意,在该语言的现代版本中(该挑战过后),i可以将其删除。

说明

使用超几何函数使用等价函数(参见等式(10)),非常简单:

在此处输入图片说明

从超几何函数的定义

在此处输入图片说明

显然,前两个参数的顺序可以互换,从而节省了一个字节。

i         % input                                                   
-2/       % divide by -2
t.5+      % duplicate and add 0.5
h         % horizontal concatenation into a vector                               
H         % number 2
4         % number literal                                          
Zh        % hypergeometric function with three inputs (first input is a vector)

1
这个答案是最短的,而且年龄大约一个半小时,所以我接受。
isaacg '16

谢谢!我几乎无法想象MATL甚至会与Pyth并驾齐驱。这是一种很难克服的语言,要做好设计!
Luis Mendo

11

视网膜59 58字节

+`(\D*)1(1*)
:$1<$2:$1>$2:$1_$2:
:(_|()<|(?<-2>)>)+:(?!\2)

接受一元输入。输入7(即1111111)花费了一段时间,但仍在不到一分钟的时间内完成。我不会比这更进一步。

在线尝试。

说明

Motzkin数字的不同特征是三个不同字符的字符串数,其中两个字符正确平衡(因此,与加泰罗尼亚语数字的密切关系相同,没有第三个独立于平衡字符的字符相同)。

.NET的平衡群体在检测正确匹配字符串非常好,所以我们简单地生成所有长度的字符串N(使用_<>为三个字符),然后我们计算有多少的正确平衡。例如,N = 4有效字符串为:

____
__<>
_<_>
_<>_
<__>
<_>_
<>__
<<>>
<><>

在挑战的定义相比,_相当于一个(1,0)步骤,<(1,1)>(1,-1)

至于实际的代码,:用作不同字符串之间的分隔符。第二个regex只是用于平衡弦的标准.NET regex的高尔夫球形式。

需要注意的是,:每个步骤中的字符串之间仅插入一个单个字符串,但是第二个正则表达式匹配前导结尾:(并且由于匹配不能重叠,这意味着在最后一步中从一个模板生成的相邻字符串不能同时匹配)。但是,这不是问题,因为这三个中的一个最多可以匹配:

  • 如果以结尾的字符串_匹配,则没有该前缀的前缀_已经正确平衡,<或者>将失去该平衡。
  • 如果字符串结尾>匹配,则该字符串 that 保持平衡>,因此_or <会失去该平衡。
  • 结尾的字符串<永远无法平衡。

可惜的是'\'具有特殊含义,否则使用'_ / \'字符会更适合问题的实质。
尼尔,2015年

9

Python 2,51字节

M=lambda n:n<1or sum(M(k)*M(n-2-k)for k in range(n))

使用Mathworld中的公式

在此处输入图片说明

通过将M[n-1]术语放入的总和中来节省字符k=n-1,给出M[-1]*M[n-1]M[-1]=1作为初始条件的一部分。

编辑:一个字符缩短递归地写总和:

M=lambda n,k=0:n<1or k<n and M(k)*M(n-2-k)+M(n,k+1)

其他方法更长的时间:

M=lambda n,i=0:n and(i>0)*M(n-1,i-1)+M(n-1,i)+M(n-1,i+1)or i==0
M=lambda n:+(n<2)or(3*~-n*M(n-2)+(n-~n)*M(n-1))/(n+2)

8

Pyth,15个字节

Ls*V+KyMb1+t_K1

这定义了一个功能y。在线尝试:演示

说明:

我们y[n]n个Motzkin的号码。我y[n]用公式计算

y[n] = dot product of (y[0], ..., y[n-1], 1) and (y[n-2], ..., y[0], 1)

请注意,第一个向量大于第二个向量(计算时除外y[0])。在这种情况下,Pyth会在第一个向量的末尾自动忽略1,以使两个向量的长度相等。

Ls*V+KyMb1+t_K1
L                 define a function y(b), which returns:
      yMb            compute the list [y[0], y[1], ..., y[b-1]]
     K               assign it to K
  *V                 vectorized multiplication of
    +K   1             * K with a 1 at the end
          +t_K1        * reverse(K), remove the first element, and append 1
 s                   return the sum (dot product)

此公式是OEIS上列出的公式之一的变体。这可能有点愚蠢。由于第一个向量的末尾为1(这使长度不相等),因此我实际上不必为递归提供基本情况。我希望两个人+...1可以打高尔夫球。原来我做不到。

您可以使用等长向量的点积来定义类似的递归,y[0] = 1并使用相同的字节数来定义基本情况。


8

CJam(20字节)

.5X]{__W%.*:++}qi*W=

在线演示

正如Mego在对该问题的评论中指出的那样,这与加泰罗尼亚语数字密切相关:将.5to 更改1为索引并将其偏移一个(或完全删除.5索引并使索引保持不变)以获得加泰罗尼亚语数字。

重复使用的是

a(n + 2)-a(n + 1)= a(0)* a(n)+ a(1)* a(n-1)+ ... + a(n)* a(0)[伯恩哈特]

从OEIS页面。加泰罗尼亚语编号的相应重复列出为

a(n)= Sum_ {k = 0..n-1} a(k)a(n-1-k)。


6

严重的是21个字节

,;╗r`;τ╜█@;u@τ╣║\*`MΣ

Quintopia的Catalan Numbers解决方案中借用了一些代码,特别是我在注释中所做的改进。

我使用以下公式:

莫兹金公式

由于nCk是,对于k > n,我将一直累加到n-1,因为这些值都将为0,因此不会影响总和。

在线尝试

说明:

,;╗r`;τ╜█@;u@τ╣║\*`MΣ
,;╗                    push input, dupe, store one copy in register 0
   r                   push range(0, n) ([0,n-1])
    `             `M   map the function:
     ;τ╜█@               dupe k, push C(n, 2*k), swap with k
          ;u@τ╣║\        push the kth Catalan number
                 *       multiply
                    Σ  sum

C(n, 2*k)现在该怎么办?
Addison Crump 2015年

@FlagAsSpam C(n,k) = nCk,或k项目池中n项目组合的数量。
Mego

哦,这比我想象的要有意义。+1。
艾迪生·克伦普

@FlagAsSpam我想我不想知道你以为是...
Mego

5

R,64字节

f=function(n)ifelse(n<2,1,f(n-1)+sum(rev(s<-sapply(2:n-2,f))*s))

还使用@xnor的python answer的Mathworld公式。感谢优先规则,2:n-2等于0:(n-2)

测试用例:

> f(0)
[1] 1
> f(1)
[1] 1
> f(5)
[1] 21
> f(10)
[1] 2188
> sapply(0:20,f)
 [1]        1        1        2        4        9       21       51      127
 [9]      323      835     2188     5798    15511    41835   113634   310572
[17]   853467  2356779  6536382 18199284 50852019

5

Mathematica,31个 30字节

AppellF1[-#/2,.5,-#/2,2,4,4]&

为了好玩,这是一个37字节的版本

Hypergeometric2F1[(1-#)/2,-#/2,2,4]&

和52字节版本

SeriesCoefficient[1-x-Sqrt[1-2x-3x^2],{x,0,#+2}]/2&

4

果冻17 14 13字节

×US;
1;HÇƓ¡1ị

这使用@PeterTaylor的答案中的递归关系。在线尝试!

怎么运行的

×US;      Define a helper link. Left argument: a (list)

×U        Multiply (×) a by its reverse (U).
  S       Compute the sum of the resulting list.
   ;      Prepend it to a.
          Return the result.

1;HÇƓ¡1ị  Define the main link.

1         Set the left argument to 1.
 ;H       Append the half of 1 to 1. Result: [1, 0.5].
    Ɠ     Read an integer n from STDIN.
   Ç ¡    Call the helper link (Ç) n times.
      1ị  Retrieve the result at index 1.

2

Mathematica,44 42 34个字节

Sum[#!/(i!(i+1)!(#-2i)!),{i,0,#}]&

35字节版本:

Coefficient[(1+x+1/x)^#,x]/#&[#+1]&

2

Pari / GP38 36 26字节

n->(1+x+x^2)^n++/n\x^n++%x

在线尝试!

使用MathWorld中的公式(11):

中号ñ=1个ñ+1个ñ+1个1个2

ñķ2ñķ2Xñ+ķ1个+X+X2ñ


A 14字节Samau使用三项式系数的第一个定义函数:);;7 2D$ⁿ$)╡$÷。我不会将其发布为答案,因为该语言比问题要新。
alephalpha

发布就好了,您只需要添加免责声明,认为提交的内容不符合要求,因为如您所说,该语言比问题新。
Alex A.

2

05AB1E13 12字节

ÝI<ãʒ.øDŸQ}g

在线尝试!

虽然大多数答案使用公式或递归关系,但这是一种简单的计数方法。

穿过网格的每个可能路径都由其y坐标列表表示。对于n个段,总共有(n + 1)个点,但是第一个和最后一个必须为0,因此需要指定(n-1)个点。

Ý           # range [0..n]
 I<         # n - 1
   ã        # cartesian power

现在,我们有了路径列表(尚不包括初始0和最终0)。通过构造,它们都不会低于0。但是,其中一些具有非法斜率(例如,从0跳到2),因此我们需要将它们过滤掉。

ʒ      }g   # count how many paths satistfy the following condition
 0.ø        # surround with 0
      Q     # is equal to
    DŸ      # its own fluctuating range

Ÿ是内置的波动范围。如果有一对不相邻的数字,它将填写缺失的数字(例如[0,2]变为[0,1,2])。仅合法路径将保持不变。

检查非法斜率的一种也许更直观的方法是üαà(确认成对的绝对差的最大值等于1)。但是,这错过了平坦的[0,0,... 0]路径,该路径花费一个额外的字节来修复。

最后,请注意,实际代码使用的是本解释所使用的位置0.ø。而不是用0包围路径,而是用路径的两个副本包围隐式输入。这会使坐标系上下颠倒和颠倒过来,但在其他方面是等效的。


2

Stax,12 个字节

îu¬@Y≤ÅÉÑ(πε

运行并调试

我不知道如何进行花式数学排版,但这基本上依赖于动态编程构造

M(0) = 1
M(1) = 1
M(n + 1) = M(n) + sum(M(k) * M(n - k - 1) for k in [0..n-1])

1

红宝石,50岁

递归关系的简单实现。

g=->n{n<2?1:(3*(n-1)*g[n-2]+(2*n+1)*g[n-1])/(n+2)}

1

脑高射炮,90个字节

(([{}]<(())>)<{({}()<{<>([({})]({}[({})]({}<>{}<>)))<>}<>>)}>){({}()<{}>)}{}({}{}[{}{}]<>)

在线尝试!

ñ02-ñ22ñķ2Cñ=2ññ-2ññ+1个


0

ES6,44个字节

f=(n,k=0)=>n<1?1:k<n&&f(k)*f(n-2-k)+f(n,k+1)

@xnor的递归Python解决方案的直接端口。需求n<1?1:,因为n<1||会使f(0)回报true


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.