加泰罗尼亚语数字


36

Catalan数OEIS)是自然数常常出现在组合的序列。

第n个加泰罗尼亚语数字是Dyck单词的数目(括号中的平衡字符串或方括号,例如[[][]];正式定义为使用两个字符a和b的字符串,这样从开头开始的任何子字符串的字符数都大于或等于number b个字符,整个字符串具有相同的a和b个字符),长度为2n。第n个加泰罗尼亚数字(对于n> = 0)也明确定义为:

从n = 0开始,前20个加泰罗尼亚数字为:

1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190...

挑战

编写一个完整的程序或函数,该程序或函数通过STDIN或可接受的替代方法获取非负整数n,并输出第n个加泰罗尼亚数字。您的程序必须至少对输入0-19有效。

输入输出

输入值

您的程序必须根据此meta post接收来自STDIN,函数参数或任何可接受的替代方法的输入。您可以将输入的数字读取为标准的十进制表示形式,一进制表示形式或字节。

  • 如果(且仅当)您的语言无法从STDIN或任何可接受的替代方法中输入内容,则它可能从程序中的硬编码变量或适当的等效语言中获取输入。

输出量

您的程序必须根据此meta post将第n个加泰罗尼亚编号输出到STDOUT,函数结果或任何可接受的替代方法您可以以标准的十进制表示形式,一元表示形式或字节形式输出加泰罗尼亚数字。

输出应包含适当的加泰罗尼亚语数字,并可以选择后面跟着一个或多个换行符。除了无法避免的语言解释器的恒定输出(例如问候语,ANSI颜色代码或缩进​​)以外,无法生成其他任何输出。


这并不是要找到最短的语言。这是关于寻找每种语言中最短的程序。因此,我不会接受答案。

在此挑战中,只要具有实现方式,就可以接受比挑战新的语言允许(甚至鼓励)自己为以前未实现的语言编写此解释器。除此之外,必须遵守所有的标准规则。大多数语言的提交都将以适当的预先存在的编码(通常为UTF-8)以字节计分。另请注意,允许使用内置函数来计算第n个加泰罗尼亚语数字。

目录

这篇文章底部的Stack Snippet会根据答案a)生成目录,a)作为每种语言最短解决方案的列表,b)作为整体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


我们可以打印/返回浮点数而不是整数吗?
Alex A.

@AlexA。这是可以接受的。
意大利面条

会有标签oeis吗?
六。

1
@Vi。有一阵子的讨论已经过去了,我们同意不需要oeis
义大利面

@Vi。这是meta文章:meta.codegolf.stackexchange.com/a/5546/8478。至于某些推理,您可以使用序列numbernumber-theory之一可靠地找到OEIS风格的挑战。给定的序列是否实际上在OEIS,完全是风马牛不相及的挑战。
马丁·恩德

Answers:


26

C,78 52 39 34 33字节

更多的C魔术(感谢xsot):

c(n){return!n?:(4+6./~n)*c(n-1);}

?: 是GNU扩展


这次通过将重复率扩展到下面(感谢xnor和Thomas Kwa):

另一个递归

c(n){return n?(4+6./~n)*c(n-1):1;}

-(n+1)替换为~n,等效于2的补码,并节省4个字节。


再次作为功能,但是这次利用以下重复性:

复发

c(n){return n?2.*(2*n++-1)/n*c(n-2):1;}

c(n)为负数输入无限递归n,尽管与该挑战无关。


由于调用函数似乎可以替代控制台I / O,因此:

c(n){double c=1,k=2;while(k<=n)c*=1+n/k++;return c;}

c(n)int并返回int


原始条目:

main(n){scanf("%d",&n);double c=1,k=2;while(k<=n)c*=1+n/k++;printf("%.0f",c);}

代替直接计算定义,公式被重写为:

改写

该公式假设n >= 2,但代码占了n = 0n = 1太。

在上面的C混乱中,nk具有与公式中相同的作用,同时c累积了乘积。所有计算都使用进行浮点运算double,这几乎总是一个坏主意,但在这种情况下,结果至少在n = 19时才是正确的,因此可以。

float 本来可以保存1个字节,但是它不够精确。


我现在无法测试,但是我认为您可以进一步缩短:c(n){return!n?:(4+6./~n)*c(n-1);}
xsot

谢谢@xsot,我不知道?:!显然,它是GNU C扩展,但我认为它仍然合格。
Stefano Sanfilippo

23

果冻,4字节

Ḥc÷‘

在线尝试!

怎么运行的

Ḥc÷‘    Left argument: z

Ḥ       Compute 2z.
 c      Hook; apply combinations to 2z and z.
  ÷‘    Divide the result by z+1.

1
“ hook”是什么意思?如何c获取2zz作为其参数?
xnor

@xnor钩子意味着函数的计算类似于f(x,g(x))。当有一个二进位函数,然后是另一个二进位函数时,解析器会将第一个函数视为钩子。
lirtosiast 2015年

5
@Dennis真的是4个字节吗?对于那些非ASCII字符,mothereff.in/ byte
Luis

@LuisMendo它可能是一个不同的编码
undergroundmonorail

3
@LuisMendo Jelly使用其自己的自定义编码默认值,其中每个字符都是一个字节。使用UTF-8,源代码确实是9个字节长。
丹尼斯

11

CJam,12个字节

ri_2,*e!,\)/

在线尝试。

除了输入11之外,您还需要告诉Java VM使用更多的内存。而且我实际上不建议超出11。在理论上,它对任何N都适用,因为CJam使用任意精度整数。

说明

CJam没有内置的二项式系数,并且从三个阶乘计算它们需要很多字节...因此我们必须做得更好。:)

ri  e# Read input and convert it to integer N.
_   e# Duplicate.
2,  e# Push [0 1].
*   e# Repeat this N times, giving [0 1 0 1 ... 0 1] with N zeros and N ones.
e!  e# Compute the _distinct_ permutations of this array.
,   e# Get the number of permutations - the binomial. There happen to be 2n-over-n of
    e# of them. (Since 2n-over-n is the number of ways to choose n elements out of 2n, and
    e# and here we're choosing n positions in a 2n-element array to place the zeros in.)
\   e# Swap with N.
)/  e# Increment and divide the binomial coefficient by N+1.

这真的很酷。+1
意大利面条

这很聪明。我尝试过计算阶乘。通常只需三个中的两个,因为其中两个相同。ri_2*m!1$m!_*/\)/在我的实现中,它仍然使用了17个字节()。唯一的好处是速度更快。:)
Reto Koradi 2015年

11

Mathematica,16 13字节

CatalanNumber

内置,无规陨石:/

非内置版本(21字节):

Binomial[2#,#]/(#+1)&

无二项式的版本(25字节):

Product[(#+k)/k,{k,2,#}]&

10

TI-BASIC,11个字节

(2Ans) nCr Ans/(Ans+1

奇怪的是,nCr的优先级高于乘法。


10

Python 3,33个字节

f=lambda n:0**n or(4+6/~n)*f(n-1)

使用重复

f(0) = 1
f(n) = (4-6/(n+1)) * f(n-1)

0的基本情况将作为处理0**n or,在1时停止n==0,否则将评估右侧的递归表达式。按位运算符~n==-n-1缩短分母并节省parens。

Python 3用于其浮点除法。Python 2可以再写一个字节来做同样的事情6.


为什么不n<1而不是0**n
feersum

@feersum它返回Truen==0,而不是1。当然可以,True == 1但是True is not 1它的打印方式有所不同。我希望这是不允许的。您知道我们是否有裁定?
xnor 2015年

我相信那很好。isinstance(True, int) is True毕竟。
feersum

2
我认为这在一般情况下仍然很棘手,而且在这里,挑战将输出指定为数字或其表示形式。但是,直到@quartata
xnor

7

J,8个字节

>:%~]!+:

这是单车火车;它使用(2x nCr x)/(x + 1)公式。在这里尝试。


7

pl,4个字节

☼ç▲÷

在线尝试。

说明

在pl中,函数将其参数移出堆栈,然后将结果推回堆栈。通常,当堆栈上没有足够的参数时,该函数只会静默失败。但是,当堆栈上的参数数量与函数的数量不相同时,会发生一些特殊的情况-输入变量_将添加到参数列表中:

☼ç▲÷

☼      double: takes _ as the argument since there is nothing on the stack
 ç     combinations: since there is only one item on the stack (and arity is 2), it adds _ to the argument list (combinations(2_,_))
  ▲    increment last used var (_)
   ÷   divide: adds _ to the argument list again

实际上,这是伪代码:

divide(combinations(double(_),_),_+1);

6

Sesos94 86 68字节

通过将阶乘-er从版本1更改为版本2,可获得8个字节。

通过n!(n+1)!一步计算获得18个字节。很大程度上受Dennis素数测试算法的启发。

十六进制转储:

0000000: 16f8de a59f17 a0ebba 7f4cd3 e05f3f cf0fd0 a0ebde  ..........L.._?......
0000015: b1c1bb 76fe18 8cc1bb 76fe1c e0fbda 390fda bde3d8  ...v.....v.....9.....
000002a: 000fbe af9d1b b47bc7 cfc11c b47bc7 cff1fa e07bda  .......{.....{.....{.
000003f: 39e83e cf07                                       9.>..

在线尝试!

使用公式a(n) = (2n)! / (n!(n+1)!)

  • 阶乘:版本1(就地,恒定内存),版本2(就地,线性内存)
  • 乘数:此处(原位,常量内存)
  • 分隔线:此处(如果不可分割,则不会停止)

组装工

set numin
set numout
get
jmp,sub 1,fwd 1,add 1,fwd 2,add 2,rwd 3,jnz
fwd 1,add 1
jmp
  jmp,sub 1,rwd 1,add 1,rwd 1,add 1,rwd 1,add 1,fwd 3,jnz
  rwd 1,sub 1,rwd 1,sub 1,rwd 1
  jmp,sub 1,fwd 3,add 1,rwd 3,jnz
  fwd 1
jnz
fwd 3
jmp
  jmp
    sub 1,rwd 1
    jmp,sub 1,rwd 1,add 1,rwd 1,add 1,fwd 2,jnz
    rwd 2
    jmp,sub 1,fwd 2,add 1,rwd 2,jnz
    fwd 3
  jnz
  rwd 1
  jmp,sub 1,jnz
  rwd 1
  jmp,sub 1,fwd 2,add 1,rwd 2,jnz
  fwd 3
jnz 
fwd 1
jmp
  jmp,sub 1,fwd 1,add 1,fwd 1,add 1,rwd 2,jnz
  fwd 1,sub 1,fwd 1
  jmp,sub 1,rwd 2,add 1,fwd 2,jnz
  rwd 1
jnz
rwd 2
jmp
  jmp
    sub 1,fwd 1
    jmp,sub 1,fwd 1,add 1,fwd 1,add 1,rwd 2,jnz
    fwd 2
    jmp,sub 1,rwd 2,add 1,fwd 2,jnz
    rwd 3
  jnz
  fwd 1
  jmp,sub 1,jnz
  fwd 1
  jmp,sub 1,rwd 2,add 1,fwd 2,jnz
  rwd 3
jnz 
fwd 1
jmp
  fwd 1,add 1,rwd 3
  jmp,sub 1,fwd 1,add 1,fwd 1,sub 1,rwd 2,jnz
  fwd 1
  jmp,sub 1,rwd 1,add 1,fwd 1,jnz
  fwd 1
jnz
fwd 1
put

脑干等效

此Retina脚本用于生成等效的Brainfuck。注意,它仅接受一位数字作为命令参数,并且不检查命令中是否包含命令。

[->+>>++<<<]>+
[[-<+<+<+>>>]<-<-<[->>>+<<<]>]>>>
[[-<[-<+<+>>]<<[->>+<<]>>>]<[-]<[->>+<<]>>>]>
[[->+>+<<]>->[-<<+>>]<]<<
[[->[->+>+<<]>>[-<<+>>]<<<]>[-]>[-<<+>>]<<<]>
[>+<<<[->+>-<<]>[-<+>]>]>


5

认真地,9个字节

,;;u)τ╣E\

十六进制转储:

2c3b3b7529e7b9455c

在线尝试

说明:

,                   Read in evaluated input n
 ;;                 Duplicate it twice
   u)               Increment n and rotate it to bottom of stack
     τ╣             Double n, then push 2n-th row of Pascal's triangle
       E            Look-up nth element of the row, and so push 2nCn
        \           Divide it by the n+1 below it.

您可以利用Pascal三角形的行是对称的事实来节省字节,因此2n第th行的中位数为C(2n,n)。因此:,;u@τ╣║/8个字节。
Mego

什么?2nCn不是第二行的最大值吗?
quintopia

是的,这也是中位数。所以,无论是M会的工作。
Mego

@Mego我担心您的中位数的实现,如果列表不是全部相同的数字,那么某些东西可以同时是中位数和最大值。如果您的意思是“在列表中间”,则可以为其选择其他名称...
quintopia 2015年

是的,它在列表的中间。对于排序列表,这是典型的统计中位数,但对于未排序列表,它只是中间(或2个中间元素的平均值)
Mego

4

JavaScript(ES6),24个字节

基于Python的答案

c=x=>x?(4+6/~x)*c(x-1):1

怎么运行的

c=x=>x?(4+6/~x)*c(x-1):1
c=x=>                     // Define a function c that takes a parameter x and returns:
     x?               :1  //  If x == 0, 1.
       (4+6/~x)           //  Otherwise, (4 + (6 / (-x - 1)))
               *c(x-1)    //  times the previous item in the sequence.

我认为这是最短的方法,但是欢迎提出建议!


4

朱莉娅,23个字节

n->binomial(2n,n)/(n+1)

这是一个接受整数并返回浮点数的匿名函数。它使用基本的二项式公式。要给它起个名字,例如f=n->...


4

Matlab,35 25字节

@(n)nchoosek(2*n,n)/(n+1)

八度,23字节

@(n)nchoosek(2*n,n++)/n

2
您可以使用@(n)函数代替匿名函数。
FryAmTheEggman 2015年

在访问工作区变量之前,我已经在这里看到了几个答案(这意味着它们已经由其他地方的用户设置了)。MATLAB / Octave中的脚本也可以显示为简单的片段。我现在已经将其重新制成函数...
costrom 2015年

1
您可以通过后递增来增加2个字节n@(n)nchoosek(2*n,n++)/n
烧杯

@beaker感谢小费!它仅适用于Octave,不适用于Matlab,因此我将其分开了
costrom 2015年

@costrom这很有趣。我猜.../++n也不行。:/
烧杯


3

Haskell,27个字节

g 0=1
g n=(4-6/(n+1))*g(n-1)

递归公式。必须有一种方法可以节省很多钱...

直接服用产品的时间增加了2个字节:

g n=product[4-6/i|i<-[2..n+1]]

您的代码在哪里从stdin读取或写入stdout?
user2845840 2015年

2
@ user2845840函数是规范中链接到的可接受的替代方法之一。
xnor 2015年

g(n-1)=> g$n-1保存一个字节。编辑:实际上这是行不通的,因为然后公式被解释为(...*g) (n-1)
所罗门诺夫的秘密

3

Dyalog APL,9个字节

+∘1÷⍨⊢!+⍨

这是单车火车;它使用(2x nCr x)/(x + 1)公式。在这里在线尝试。


3

C,122 121 119 108个字节

main(j,v)char**v;{long long p=1,i,n=atoi(v[1]);for(j=0,i=n+1;i<2*n;p=(p*++i)/++j);p=n?p/n:p;printf("%d",p);}

我使用gcc(GCC)3.4.4(cygming special,gdc 0.12,使用dmd 0.125)在Windows cygwin环境中进行编译。输入来自命令行。它类似于Sherlock9的Python解决方案,但循环被组合为一个,以避免溢出,并获得高达第20个加泰罗尼亚语数字的输出(n = 19)。


1
您可以在main定义中的逗号后删除空格以保存字节。
Alex A.

好的,我现在就编辑帖子
cleblanc 2015年

您可以使用char**v而不是多保存2个字节char *v[]。(之前的空格*是不需要的,并且类型是等效的。)
Mat Mat

果然,效果很好。感谢Mat
cleblanc 2015年

这会使用提示页面中的一些内容来缩短它。请注意,尽管我为Ideone硬编码了一个值n
FryAmTheEggman 2015年

3

Javagony,223个字节

public class C{public static int f(int a,int b){try{int z=1/(b-a);}catch(Exception e){return 1;}return a*f(a+1,b);}public static void main(String[]s){int m=Integer.parseInt(s[0])+1;System.out.println(f(m,2*m-1)/f(1,m)/m);}}

完全扩展:

public class C {
    public static int f(int a,int b){
        try {
            int z=1/(b-a);
        } catch (Exception e){
            return 1;
        }
        return a*f(a+1,b);
    }
    public static void main(String[] s){
        int m=Integer.parseInt(s[0])+1;
        System.out.println(f(m,2*m-1)/f(1,m)/m);
    }
}

Esolangs参赛无所谓-只要您使用比赛前制作的口译员,那都是很好的和有效的。
艾迪生·克伦普

反正也不会赢^^
瑕疵的

是Java,是的。
Rɪᴋᴇʀ

1
@Riker好吧,它比Java差。
雅各布

2

Japt,16个字节

甚至Mathematica也较短。 :-/

U*2ª1 o àU l /°U

在线尝试!

脱节和解释

U*2ª 1 o àU l /° U
U*2||1 o àU l /++U

         // Implicit: U = input number
U*2||1   // Take U*2. If it is zero, take 1.
o àU     // Generate a range of this length, and calculate all combinations of length U.
l /++U   // Take the length of the result and divide by (U+1).
         // Implicit: output result

替代版本,基于递归公式:

C=_?(4+6/~Z *C$(Z-1):1};$C(U

2

Vitsy,13字节

VV2*FVF/V1+F/
V              Capture the input as a final global variable.
 V             Push it back.
  2*           Multiply it by 2
    F          Factorial.
     VF        Factorial of the input.
       /       Divide the second to top by the first.
        V1+    1+input
           F   Factorial.
            /  Divide.

这是Vitsy中的功能。您问如何使它成为执行此操作的程序?串联N。C:

在线尝试!


2

银河1.5.14,14字节

':2K;*Ny;1+/A!

说明

'               # read input from the command line
 :              # duplicate the TOS
  2      1      # push integer to the stack
   K            # push a Pythonic range(0, TOS) as a list
    ;   ;       # swap the TOS and the STOS
     *          # multiply the TOS and STOS
      N         # push a list of the permutations of the TOS (for lists)
       y        # push the length of the TOS
          +     # add the STOS to the TOS
           /    # divide the TOS by the STOS
            A   # push the integer representation of the TOS
             !  # output the TOS

或者,在很多更有效的版本:


银河1.5.14,22字节

'1%{;K£1+k1-6;/4+*}A!

说明

'                      # read input from the command line
 1     1  1 6  4       # push integer to the stack
  %{  £           }    # for loop
    ;        ;         # swap the TOS and the STOS
     K                 # push a Pythonic range(0, TOS) as a list
        +       +      # add the TOS and STOS
         k             # push the negative absolute value of the TOS
           -           # subtract the STOS from the TOS
              /        # divide the TOS by the STOS
                 *     # multiply the TOS and the STOS
                   A   # push the integer representation of the TOS
                    !  # output the TOS

用法

python3 milkyway.py <path-to-code> -i <input-integer>

2

Clojure / ClojureScript,53个字节

(defn c[x](if(= 0 x)1(*(c(dec x))(- 4(/ 6(inc x))))))

Clojure可能使打高尔夫球变得很沮丧。它虽然很精简,但仍然很易读,但是其中一些更真实的功能确实很冗长。 (inc x)比更加惯用(+ x 1),“感觉”更简洁,但实际上并没有保存字符。编写操作链比更好(->> x inc (/ 6) (- 4)),但是实际上比用丑陋的方法做的要长。


2

Prolog,42个字节

使用Prolog几乎总是使用递归。

码:

0*1.
N*X:-M is N-1,M*Y,X is(4-6/(N+1))*Y.

例:

19*X.
X = 1767263190.0

在这里在线尝试


您在*这里重新定义符号吗?
圣保罗Ebermann

@PaŭloEbermann不完全是。我正在定义一个称为*的新二元谓词。我仍然可以使用常规算术运算。在上面的程序中,M * Y是我定义的谓词,而(4-6 /(N + 1))* Y是正则乘法。
Emigna

它比将其写为p(X,Y)略短:-这对于编写代码很好。
Emigna


2

锡兰,60字节

Integer c(Integer n)=>(1:n).fold(1)((p,i)=>p*(n+i)/i)/(n+1);

由于Ceylon的Integer是带符号的64位数字(C 31有溢出,将被计算为-4050872099593203),因此该代码最多可使用C 30

我不知道锡兰(Ceylon)是否具有任何内置的高级数学函数,但是导入正确的程序包可能比仅凭脚步计算更长的时间。

// Catalan number C_n
//
// Question:  http://codegolf.stackexchange.com/q/66127/2338
// My answer: http://codegolf.stackexchange.com/a/66425/2338

Integer c(Integer n) =>
        // sequence of length n, starting at 1.
        (1:n)
        // starting with 1, for each element i, multiply the result
        // of the previous step by (n+i) and then divide it by i.
    .fold(1)((p, i) => p * (n + i) / i)
        // divide the result by n+1.
        / (n + 1);

2

R,35 28 16字节

numbers::catalan

编辑:使用内置的数字包。



2

05AB1E,6个字节

Dxcr>/

说明:

Code:     Stack:               Explanation:

Dxcr>/

D         [n, n]               # Duplicate of the stack. Since it's empty, input is used.
 x        [n, n, 2n]           # Pops a, pushes a, a * 2
  c       [n, n nCr 2n]        # Pops a,b pushes a nCr b
   r      [n nCr 2n, n]        # Reverses the stack
    >     [n nCr 2n, n + 1]    # Increment on the last item
     /    [(n nCr 2n)/(n + 1)] # Divides the last two items
                               # Implicit, nothing has printed, so we print the last item

2

R,28个字节

未使用套件,因此比以前的答案稍长

choose(2*(n=scan()),n)/(n+1)
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.