Kết hợp toán học


11

Viết chương trình nhận đầu vào như:

n,k

mà sau đó tính toán:

Kết hợp n và k.  (C (n, k))

và sau đó in kết quả.


Một ví dụ bằng số:

Đầu vào:

5,2

Tính toán nội bộ:

(5!) / (3! X2!)

Đầu ra in:

10

Tôi muốn thấy một câu trả lời đánh bại giải pháp trăn của tôi gồm 65 ký tự, nhưng tất cả các ngôn ngữ rõ ràng đều được chào đón.

Đây là giải pháp của tôi:

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

Biên tập:

Tôi thừa nhận rằng câu hỏi này là từ câu đố kết hợp toán học trang web codegolf . Tôi biết rằng câu trả lời của tôi có vẻ như không có nhiều tiến bộ có thể được thực hiện trên đó, nhưng các nhà lãnh đạo của câu đố này đã giải quyết nó trong gần một nửa số nhân vật.

Số ký tự thấp nhất hiện tại theo ngôn ngữ là:

Perl: 35

Hồng ngọc: 36

Con trăn: 39

PHP: 62


Chức năng hay chương trình đầy đủ? Mô tả của bạn cho biết hàm trả về kết quả chính xác, nhưng ví dụ của bạn là một chương trình đầy đủ in nó.
Ventero

@Ventero Bạn nói đúng ý tôi là chương trình. Xin lỗi vì điều đó.
Backus

3
Nói chung, các khái niệm toán học cơ bản không phải là câu hỏi golf tuyệt vời vì J, APL, Maple, Mathematica và nhiều người khác sẽ tích hợp chúng. Ngoài ra, hãy cụ thể hơn một chút về định dạng đầu vào và đầu ra, và cung cấp kết quả ví dụ - Tôi không thể cho biết nếu bạn có nghĩa là 5 chọn 2 hoặc 2 chọn 5 ở đây.
Jesse Millikan

@Jlie Tôi nhận được thử thách này từ một trang web khác chỉ cho phép các ngôn ngữ chính, tôi sẽ nhớ hướng dẫn này trong tương lai. Tôi đã chỉnh sửa câu hỏi của mình để thử và làm cho các yêu cầu thử thách rõ ràng hơn, cho tôi biết nếu nó đủ rõ ràng hay không.
Backus

Tôi là người mới, vì vậy chúng tôi ở cùng một chiếc thuyền. Tuy nhiên, đừng tóm tắt kết quả; họ sẽ chỉ bị lỗi thời Chỉ cần bỏ phiếu và (nếu thích hợp) chấp nhận câu trả lời. (Ngoài ra, bạn sẽ khiến mọi người không hài lòng nếu bạn bỏ qua câu trả lời của J và GolfScript mà không có lý do.)
Jesse Millikan

Câu trả lời:


11

APL, 3 byte

⎕!⎕

Hoặc đối với những người có trình duyệt không hiển thị ở trên, trong kết xuất ASCII:

{Quad}!{Quad}

3
Để hoàn toàn phù hợp với n,kđầu vào, bạn phải làm !/⌽⎕.
bến tàu


10

C 96

Với I / O (mất khoảng 34 ký tự). Đã thêm một vài dòng mới để làm cho nó dễ đọc.

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

Bây giờ nếu bạn tha thứ cho tôi, tôi có ASCII n chọn k tên lửa để bắt.

    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 * * |
|     *      *    \
*/    //       *  */


6

GolfScript 21

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

Không đặc biệt ngắn, GolfScript thiếu chức năng giai thừa thực, tuy nhiên đây phải là thao tác dữ liệu độc ác nhất mà tôi từng thực hiện, điều này đòi hỏi một dấu vết ngăn xếp:

"5,2" Dữ liệu trên ngăn xếp từ đầu vào.
~Lệnh Eval, lưu ý rằng, là một toán tử biến một số thành một mảng.
[0 1 2 3 4] 2
~Nhị phân không.
[0 1 2 3 4] -3
)Tăng.
[0 1 2 3 4] -2
>Kết thúc mảng, -2 làm tham số để lấy 2 phần tử cuối cùng.
[3 4]
.Phần tử trùng lặp.
[3 4] [3 4]
,Độ dài mảng.
[3 4] 2
,Biến số thành mảng.
[3 4] [0 1]
]Tạo mảng.
[[3 4] [0 1]]
{{)}%{*}*}Khối mã.
[[3 4] [0 1]] {{)}% {*} *}
%Thực thi khối một lần cho mỗi phần tử của mảng. Phần sau chỉ thể hiện vòng lặp đầu tiên.
[3 4]
{)}%Tăng từng phần tử mảng.
[4 5]
{*}Khối chứa một lệnh nhân.
[4 5] {*}
*"Gấp" mảng bằng lệnh khối, trong trường hợp này tạo thành sản phẩm của tất cả các phần tử.
20
Sau khi vòng lặp lớn kết thúc, nó trả về một mảng với kết quả.
[20 2] Giải
~cấu trúc mảng.
20 2
/Sư đoàn.
10


6

Ruby 1.9, 52 46 (42) ký tự

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

Nếu stderr bị bỏ qua:

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

Ruby 1.8, 43 ký tự, không có đầu ra bổ sung cho thiết bị lỗi chuẩn:

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

Chỉnh sửa:

  • (52 -> 48) Tìm thấy một cách ngắn hơn để phân tích đầu vào
  • (48 -> 46) Ít vòng lặp hơn, tệ hơn.

4

Con trăn (56)

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

Mã Ungolfed và một số giải thích về một phím tắt để tính hệ số nhị thức. (Lưu ý: Có một số hiểu biết mà tôi chưa tìm ra để xuống phiên bản 39 char; Tôi không nghĩ rằng phương pháp này sẽ đưa bạn đến đó.)

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

Bạn có thể cung cấp một ví dụ vô căn cứ về kịch bản của bạn?
Backus

Chúng ta có thể sử dụng *để phân tích cú pháp đầu vào của biểu mẫu 4545 78không?
Quixotic

Thật không may, không, nhưng đó không phải *là vấn đề. 4545 78không phải là biểu thức Python hợp lệ, vì vậy input()sẽ tăng a SyntaxError. Thủ thuật này phụ thuộc hoàn toàn vào vấn đề yêu cầu x,y. Nếu bạn có một chức năng đọc x yvà trả về một tuple, thì bạn có thể sử dụng *với chức năng đó tốt.


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 ký tự là đầu vào, phân tích cú pháp và đầu ra. Các nhân vật khác !, là n chọn k.

Hiện tại tôi không có Windows để thử nghiệm điều này, nhưng tôi tin rằng nó nên hoạt động ở đó.



2

Perl 6 (55)

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

2

RPL (22)

(không sử dụng chức năng COMB tích hợp)

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

2

Q ( 50 45)

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

Bạn có thể loại bỏ một vài ký tự ở trên bằng cách xóa dấu ngoặc thừa và sử dụng 1 * / thay vì prd.

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

2

Toán học 12

Đơn giản, tích hợp chức năng.

n~Binomial~k

2

Perl 6 , 25 16 byte

-9 byte nhờ nwellnhof

+*o&combinations

Hãy thử trực tuyến!

Hàm ẩn danh có hai số và trả về một số nguyên. Điều này sử dụng tích hợp combinationsvà chuyển đổi danh sách trả về thành int.



@nwellnhof Ah, tôi không nhận ra combinationscó thể lấy số thay vì danh sách
Jo King

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

Con trăn (54)

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

Về cơ bản giống như Python ở trên, nhưng tôi đã loại bỏ bốn byte bằng cách loại bỏ

and 1

từ định nghĩa hàm. Tuy nhiên, điều này dẫn đến hàm trả về True thay vì 1 nếu k = 0, nhưng điều này có thể được sửa bằng cách nhân với 1 trước khi in, vì 1 * True = 1, do đó thêm hai byte.


1

J, 11 ký tự

!~/".1!:1[1

Lấy đầu vào từ bàn phím.

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

0

Haskell (80)

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

Nhưng, nếu đầu vào ở định dạng x yđược cho phép thay vì ở định dạng x,y, thì 74 ký tự:

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


0

Con trăn (52)

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

Cải thiện từ hai cái còn lại bằng cách sử dụng print+để chuyển đổi kết quả ftừ booleansang inttrong trường hợp k==0.

Vẫn không biết làm thế nào để thu nhỏ nó xuống 39, tôi tự hỏi liệu họ có đang sử dụng lambda không.


0

(OP chỉ chỉ định một cách lỏng lẻo phương thức / định dạng đầu vào và đầu ra, vì vậy những điều sau đây có vẻ chấp nhận được.)

Sage Notebook ( 39 41 40)

Trong ô hiện tại,

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

trong đó đầu vào trong biểu mẫu n,kđược nhập và đánh giá trong ô trước. Điều này mô phỏng "đầu vào dòng lệnh" bằng cách gán nó cho _(tương tự như các đối số dòng lệnh).

Sage Notebook ( 42 44 43)

Ngoài ra, sử dụng "đầu vào trong nguồn" (chỉ có các x=ký tự và dòng mới thêm vào điểm số), ví dụ:

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

Cả hai cách tiếp cận này rõ ràng là những câu trả lời từ những câu trả lời trước đó của những người khác.



0

Javascript, 27 byte

Đầu tiên là các giải pháp 35 byte của riêng tôi:

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

Hay cách khác,

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

Việc đầu tiên làm việc đệ quy, với (n,k) = (n-1,k) + (n-1,k-1)quy tắc đơn giản . Thứ hai sử dụng đó (n,k) = (n-1,k-1) * n/k.

BIÊN TẬP

Tôi chỉ nhận thấy giải pháp của Arnould trong một bản sao này:

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

Đó là một con số nhỏ hơn 8 byte (27 byte)


0

TI-BASIC, 16 ký tự (8 byte)

Ans(1) nCr Ans(2

Đầu vào là một danh sách có độ dài 2 in Ans.
Đầu ra là kết quả của công thức được xác định ở đây .

Nếu giải pháp trên không đủ, thì giải pháp 35 ký tự (24 byte) sau đây cũng hoạt động:

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

Lưu ý: TI-BASIC là ngôn ngữ được mã hóa. Số lượng ký tự không bằng số byte.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.