数学组合


11

编写一个程序,输入如下内容:

n,k

然后计算:

n和k的组合。 (C(n,k))

然后打印结果。


数值示例:

输入:

5,2

内部计算:

(5!)/(3!x2!)

打印输出:

10

我想看到一个超过65个字符的python解决方案的答案,但是显然所有语言都欢迎。

这是我的解决方案:

n,k=input();f=lambda x:+(x<2)or x*f(x-1);print f(n)/(f(k)*f(n-k))

编辑:

我承认这个问题来自codegolf网站的数学组合难题。我知道我的回答似乎无法在此问题上取得很大进展,但是这个难题的领袖们已经解决了将近一半的字符。

当前按语言分类的最低字符数为:

Perl:35

红宝石:36

的Python:39

PHP的:62


功能还是完整程序?您的描述说函数可以返回正确的结果,但是您的示例是一个完整的程序,可以打印出来。
Ventero 2011年

@Ventero你是对的,我的意思是程序。对于那个很抱歉。
backus 2011年

3
通常,基本的数学概念并不是高尔夫课程的主要问题,因为J,APL,Maple,Mathematica和许多其他工具都将内置这些概念。此外,请更加详细地介绍输入和输出格式,并提供示例结果-我不能告诉您是指5选择2还是2选择5。
杰西·米利坎

@Jesse我是从另一个仅允许使用主要脚本语言的网站获得挑战的,我会在将来记住该指南。我编辑了我的问题,试图使挑战要求更加清晰,让我知道它是否足够清晰。
backus 2011年

我是新手,所以我们几乎都在同一条船上。但是,请不要汇总结果。他们只会过时了。只需投票并(如果适用)接受答案即可。(此外,如果您无缘无故忽略J和GolfScript答案,也会使人感到不高兴。)
Jesse Millikan

Answers:


11

APL,3个字节

⎕!⎕

或者,对于那些浏览器无法呈现以上内容的用户,可以使用ASCII呈现:

{Quad}!{Quad}

3
要完全符合n,k输入,您必须要做!/⌽⎕
marinus 2012年


10

C 96

使用I / O(大约需要34个字符)。添加了一些换行符以使其可读。

main(a,b,c,d){scanf("%d,%d",&a,&b);
d=a-b;for(c=1;a>b;){c*=a--;}for(;d;)
{c/=d--;}printf("%d",c);}

现在,如果您能原谅我,我有一个ASCII码n选择k个火箭。

    d;main(a
   ,         b
  ,           c
 )  int        a
 ;   {scanf    (
 (   "%d %d"   )
 ,   &a,  &b   )
 ;   d    =a   -
 b   +     b   -
 b   *     1   ;
 a             -
 a  ;for    (  c
 =  1;a>   b   ;
 )  {c=   c    *
 (  (a-- )     )
 ;  }for(      b
 =  b + 1      ;
 d  ;    )     {
 c  =     c    /
 (  d--    )   ;
  }           {
  }           {
   }         (
  printf("%d",c)
 )      ;       }
/*     *  *   * *\
 * * X   * 8 * * |
|     *      *    \
*/    //       *  */

7

GolfScript,17个字符

此解决方案可以正确处理类似k = 0或k = 1的情况。

~>.,,]{1\{)*}/}//

类阶乘部分基于先前的答案


6

高尔夫脚本21

~~)>.,,]{{)}%{*}*}%~/

并不是特别简短,GolfScript缺少真正的阶乘函数,但这必须是我做过的最邪恶的数据操作,这需要堆栈跟踪:

“ 5,2”来自输入的堆栈数据。
~Eval命令,请注意,是将数字转换为数组的运算符。
[0 1 2 3 4] 2
~二进制不。
[0 1 2 3 4] -3
)递增。
[0 1 2 3 4] -2
>以数组的结尾,-2作为参数来获取最后2个元素。
[3 4]
.重复的元素。
[3 4] [3 4]
,数组长度。
[3 4] 2
,将数字转到数组。
[3 4] [0 1]
]创建数组。
[[3 4] [0 1]]
{{)}%{*}*}代码块。
[[3 4] [0 1]] {{)}%{*} *}
%对数组的每个元素执行一次块。以下部分仅演示第一个循环。
[3 4]
{)}%递增每个数组元素。
[4 5]
{*}包含乘法命令的块。
[4 5] {*}
*使用block命令“折叠”数组,在这种情况下,将所有元素乘积。
20
大循环完成后,它将返回一个包含结果的数组。
[20 2]
~解构数组。
20 2
/师。
10


6

Ruby 1.9, 52 46(42)个字符

eval"A,B="+gets;i=0;p eval"(A-B+i+=1)/i*"*B+?1

如果忽略stderr:

eval"A,B=I="+gets;p eval"I/(A-I-=1)*"*B+?1

Ruby 1.8,43个字符,没有附加输出到stderr:

eval"a,b=i="+gets;p eval"i/(a-i-=1)*"*b+"1"

编辑:

  • (52-> 48)找到了一种解析输入的较短方法
  • (48-> 46)更少的循环,更多的评估。

4

巨蟒(56)

f=lambda n,k:k<1and 1or f(n-1,k-1)*n/k;print f(*input())

非高尔夫代码和一些用于计算二项式系数的捷径的解释。(注意:我只是想出一些洞见才能了解39个字符的版本;我认为这种方法不会帮助您。)

# Since choose(n,k) =
#
#     n!/((n-k)!k!)
#
#          [n(n-1)...(n-k+1)][(n-k)...(1)]
#        = -------------------------------
#            [(n-k)...(1)][k(k-1)...(1)]
#
# We can cancel the terms:
#
#     [(n-k)...(1)]
#
# as they appear both on top and bottom, leaving:
#
#    n (n-1)     (n-k+1)
#    - ----- ... -------
#    k (k-1)       (1)
#
# which we might write as:
#
#      choose(n,k) = 1,                      if k = 0
#                  = (n/k)*choose(n-1, k-1), otherwise
#
def choose(n,k):
    if k < 1:
        return 1
    else:
        return choose(n-1, k-1) * n/k

# input() evaluates the string it reads from stdin, so "5,2" becomes
# (5,2) with no further action required on our part.
#
# In the golfed version, we make use of the `*` unpacking operator, 
# to unpack the tuple returned by input() directly into the arguments
# of f(), without the need for intermediate variables n, k at all.
#
n, k = input()

# This line is left as an exercise to the reader.
print choose(n, k)

您能提供一个完整的脚本示例吗?
backus 2011年

我们可以*用来解析表单的输入4545 78吗?
Quixotic

不幸的是,不是,但这不是*问题所在。4545 78不是有效的Python表达式,因此input()会引发SyntaxError。这个技巧完全取决于要解决的问题x,y。如果您有一个读取x y并返回一个元组的函数,那么就可以使用*它。


3

Windows PowerShell,57

$a,$b=iex $input
$p=1
for($a-=$b;$a-ge1){$p*=1+$b/$a--}$p

3

J,33 36

(":!~/".;._1}:toJ',',1!:1(3))1!:2(4)

输入,解析和输出35个字符。另一个字符!n是n选择k。

我目前没有Windows可以对此进行测试,但是我认为它应该可以在其中运行。


3

Q,32个字符

{f:{1*/1.+(!)x};f[x]%f[y]*f x-y}

2

Perl 6(55)

my ($a,$b)=lines;$_=1;for 1..$a-$b {$_+=$_*$b/$^a};.say

2

角色扮演(22)

(不使用内置的COMB功能)

→ n k 'n!/(k!*(n-k)!)'

2

问(50 45)

 f:{(prd 1.+til x)%((prd 1.+til y)*prd 1.+til x-y)}

您可以通过删除多余的括号并使用1 * /代替prd来将上面的字符剃掉一些。

f:{(1*/1.+til x)%(1*/1.+til y)*1*/1.+til x-y}

2

Mathematica 12

简单,内置的功能。

n~Binomial~k


1

PHP(71 79

<?$a=fgetcsv(STDIN);$x=1;while($a[1]-$i)$x=$x*($a[0]-++$i+1)/$i;echo$x;

<?php $a=fgetcsv(STDIN);$x=1;while(++$i<=$a[1])$x=$x*($a[0]-$i+1)/$i;echo $x?>


1

巨蟒(54)

f=lambda n,k:k<1or f(n-1,k-1)*n/k;print 1*f(*input())

本质上与上面的Python相同,但是我通过删除

and 1

从函数定义。但是,如果k = 0,这将导致函数返回True而不是1,但这可以通过在打印之前乘以1来解决,因为1 * True = 1,因此增加了两个字节。


1

J,11个字符

!~/".1!:1[1

从键盘获取输入。

    !~/".1!:1[1
5,2
10

0

哈斯克尔(80)

f(_,0)=1
f(n,k)=n/k*f(n-1,k-1)
main=getLine>>=putStr.show.f.read.(++")").('(':)

但是,如果x y允许输入格式而不是格式,则为x,y74个字符:

f[_,0]=1
f[n,k]=n/k*f[n-1,k-1]
main=interact$show.f.map read.take 2.words


0

巨蟒(52)

 f=lambda n,k:k<1or f(n-1,k-1)*n/k;print+f(*input())

通过使用case print+ffrom boolean到to的转换结果,从其他两个方面进行了改进。intk==0

仍然不知道如何将其缩小到39,我想知道他们是否正在使用lambda。


0

(OP仅宽松地指定了输入和输出方法/格式,因此以下内容似乎可以接受。)

鼠尾草笔记本(39 41 40)

在当前单元格中

f=lambda n,k:k<1or f(n-1,k-1)*n/k;+f(*_)

n,k前面的单元格中输入并评估表格中的输入的位置。通过将其分配给_(类似于命令行参数)来模拟“命令行输入” 。

鼠尾草笔记本(42 44 43)

或者,使用“源内输入”(仅将x=和和换行符添加到乐谱中),例如,

x=5,2
f=lambda n,k:k<1or f(n-1,k-1)*n/k;+f(*x)

这两种方法显然都是从其他人的早期答案中衍生而来的。



0

Javascript,27个字节

首先是我自己的35字节解决方案:

f=(n,k)=>n-k&&k?f(--n,k)+f(n,k-1):1

或者,

f=(n,k,i=k)=>i?f(n-1,k-1,i-1)*n/k:1

第一个以简单(n,k) = (n-1,k) + (n-1,k-1)规则递归地工作。第二个使用那个(n,k) = (n-1,k-1) * n/k

编辑

我刚刚注意到Arnould的解决方案重复了一下:

f=(n,k)=>k?n*f(n-1,k-1)/k:1

这少了8个字节(27个字节)


0

TI-BASIC,16个字符(8个字节)

Ans(1) nCr Ans(2

输入是长度为2 in的列表Ans
输出是此处定义的公式的结果

如果上述解决方案不能满足要求,那么以下35个字符(24字节)的解决方案也可以使用:

Ans(2)!⁻¹(Ans(1)-Ans(2))!⁻¹Ans(1)!

注意: TI-BASIC是一种标记化语言。字符数不等于字节数。

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.