Kombinasi Matematika

11

Tulis program yang mengambil input seperti:

n,k

yang kemudian menghitung:

Kombinasi n dan k.  (C (n, k))

dan kemudian mencetak hasilnya.


Contoh numerik:

Memasukkan:

5,2

Perhitungan internal:

(5!) / (3! X2!)

Hasil cetak:

10

Saya ingin melihat jawaban yang mengalahkan solusi python saya dengan 65 karakter, tetapi semua bahasa jelas diterima.

Inilah solusi saya:

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

Edit:

Saya akui bahwa pertanyaan ini berasal dari teka-teki kombinasi matematis situs web codegolf . Saya tahu bahwa jawaban saya mungkin terlihat seperti tidak banyak kemajuan dapat dibuat di atasnya, tetapi para pemimpin teka-teki ini telah memecahkannya dalam hampir setengah karakter.

Jumlah karakter terendah saat ini menurut bahasa adalah:

Perl: 35

Ruby: 36

Python: 39

PHP: 62

backus
sumber
Fungsi atau program lengkap? Deskripsi Anda mengatakan fungsi yang mengembalikan hasil yang benar, tetapi contoh Anda adalah program lengkap yang mencetaknya.
Ventero
@Ventero Anda benar maksud saya program. Maaf soal itu.
backus
3
Secara umum, konsep matematika dasar bukanlah pertanyaan golf yang hebat karena J, APL, Maple, Mathematica, dan banyak lagi yang lain akan membuatnya terintegrasi. Juga, lebih spesifik tentang format input dan output, dan berikan contoh hasil - Saya tidak bisa katakan apakah maksud Anda 5 pilih 2 atau 2 pilih 5 di sini.
Jesse Millikan
@Jesse Saya mendapat tantangan ini dari situs web lain yang hanya memungkinkan bahasa skrip utama, saya akan mengingat pedoman ini di masa depan. Saya mengedit pertanyaan saya untuk mencoba dan membuat persyaratan tantangan lebih jelas, beri tahu saya apakah cukup jelas atau tidak.
backus
Saya baru, jadi kami berada di kapal yang sama. Namun, jangan meringkas hasilnya; mereka hanya akan ketinggalan jaman. Cukup pilih dan (jika perlu) terima jawaban. (Juga, Anda akan membuat orang tidak senang jika Anda mengabaikan jawaban J dan GolfScript tanpa alasan.)
Jesse Millikan

Jawaban:

11

APL, 3 byte

⎕!⎕

Atau bagi mereka yang browsernya tidak merender hal di atas, dalam rendering ASCII:

{Quad}!{Quad}
jpjacobs
sumber
3
Agar sepenuhnya sesuai dengan n,kinput, Anda harus melakukannya !/⌽⎕.
marinus
10

R (11 Karakter)

choose(n,r)
skeevey
sumber
10

C 96

Dengan I / O (yang membutuhkan waktu sekitar 34 karakter). Menambahkan beberapa baris baru agar dapat dibaca.

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

Sekarang jika Anda permisi, saya punya ASCII dan memilih roket untuk ditangkap.

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

GolfScript, 17 karakter

Solusi ini menangani kasus seperti k = 0 atau k = 1 dengan benar.

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

Bagian seperti faktorial didasarkan pada jawaban sebelumnya .

Nabb
sumber
6

GolfScript 21

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

Tidak terlalu pendek, GolfScript tidak memiliki fungsi faktorial yang nyata, namun ini harus menjadi manipulasi data paling jahat yang pernah saya lakukan, ini membutuhkan jejak stack:

"5,2" Data pada stack dari input.
~Perintah Eval, perhatikan bahwa, adalah operator yang mengubah angka menjadi array.
[0 1 2 3 4] 2
~Biner tidak.
[0 1 2 3 4] -3
)Selisih.
[0 1 2 3 4] -2
>Ambil akhir array, -2 sebagai parameter untuk mendapatkan 2 elemen terakhir.
[3 4]
.Elemen rangkap.
[3 4] [3 4]
,Panjang array.
[3 4] 2
,Ubah nomor menjadi array.
[3 4] [0 1]
]Buat array.
[[3 4] [0 1]]
{{)}%{*}*}Blok kode.
[[3 4] [0 1]] {{)}% {*} *}
%Eksekusi blok satu kali untuk setiap elemen array. Bagian berikut hanya menunjukkan loop pertama.
[3 4]
{)}%Setiap elemen array bertambah.
[4 5]
{*}Blok yang berisi perintah gandakan.
[4 5] {*}
*"Lipat" array menggunakan perintah blok, yang dalam hal ini membuat produk dari semua elemen.
20
Setelah loop besar selesai, ia mengembalikan array dengan hasilnya.
[20 2]
~Dekonstruksi array.
20 2
/Divisi.
10

aaaaaaaaaaaa
sumber
6

Ruby 1.9, 52 46 (42) karakter

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

Jika stderr diabaikan:

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

Ruby 1.8, 43 karakter, tidak ada output tambahan untuk stderr:

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

Suntingan:

  • (52 -> 48) Menemukan cara yang lebih pendek untuk mem-parsing input
  • (48 -> 46) Lebih sedikit perulangan, lebih banyak eval.
Ventero
sumber
4

Python (56)

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

Kode tidak dikelompokkan dan beberapa penjelasan tentang cara pintas untuk menghitung koefisien binomial. (Catatan: Ada beberapa wawasan yang saya belum tahu untuk turun ke versi char 39; Saya tidak berpikir pendekatan ini akan membawa Anda ke sana.)

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

sumber
Bisakah Anda memberikan contoh naskah Anda yang tidak dikoleksi?
backus
Bisakah kita gunakan *untuk mem-parsing input formulir 4545 78?
Quixotic
Sayangnya, tidak, tapi bukan *itu masalahnya. 4545 78bukan ekspresi Python yang valid, jadi input()akan memunculkan a SyntaxError. Trik ini sepenuhnya tergantung pada masalah yang diminta x,y. Jika Anda memiliki fungsi yang membaca x ydan mengembalikan tuple, maka Anda dapat menggunakannya *dengan baik.
4

RPL (4)

(menggunakan fungsi bawaan)

COMB
oliver
sumber
3

Windows PowerShell, 57

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

J, 33 36

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

35 karakter adalah input, parsing dan output. Karakter lainnya !,, adalah n pilih k.

Saya tidak memiliki Windows di sekitar untuk pengujian ini saat ini, tetapi saya percaya itu harus bekerja di sana.

Jesse Millikan
sumber
3

Q, 32 karakter

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

Perl 6 (55)

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

RPL (22)

(tidak menggunakan fungsi COMB bawaan)

→ n k 'n!/(k!*(n-k)!)'
oliver
sumber
2

Q ( 50 45)

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

Anda dapat mencukur beberapa karakter dari yang di atas dengan menghapus tanda kurung yang berlebihan dan menggunakan 1 * / bukannya prd.

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

Mathematica 12

Langsung, fungsi bawaan.

n~Binomial~k
DavidC
sumber
2

Perl 6 , 25 16 byte

-9 byte terima kasih kepada nwellnhof

+*o&combinations

Cobalah online!

Fungsi anonim yang mengambil dua angka dan mengembalikan int. Ini menggunakan bawaan combinationsdan mengonversi daftar yang dikembalikan ke int.

Jo King
sumber
16 byte
nwellnhof
@nwellnhof Ah, saya tidak sadar combinationsbisa mengambil nomor alih-alih daftar
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?>

mellamokb
sumber
1

Python (54)

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

Pada dasarnya sama dengan yang Python di atas, tapi saya mencukur empat byte dengan menjatuhkan

and 1

dari definisi fungsi. Namun, ini menghasilkan fungsi mengembalikan Benar bukan 1 jika k = 0, tetapi ini dapat diperbaiki dengan mengalikan dengan 1 sebelum mencetak, karena 1 * Benar = 1, sehingga menambahkan dua byte.

Tor
sumber
1

J, 11 karakter

!~/".1!:1[1

Mengambil input dari keyboard.

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

Haskell (80)

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

Tetapi, jika input dalam format x ydiperbolehkan dan bukan dalam format x,y, itu 74 karakter:

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

Scala 54

val n,k=readInt
((k+1)to n product)/(1 to(n-k)product)
Pengguna tidak diketahui
sumber
0

Python (52)

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

Ditingkatkan dari dua lainnya dengan menggunakan print+untuk mengkonversi hasil fdari booleanke intdalam kasus k==0.

Masih tidak tahu bagaimana cara mengecilkannya menjadi 39, saya bertanya-tanya apakah mereka menggunakan lambda sama sekali.

Andrea Ambu
sumber
0

(OP hanya secara spesifik menentukan metode / format input & output, sehingga yang berikut tampaknya dapat diterima.)

Sage Notebook ( 39 41 40)

Di sel saat ini,

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

di mana input dalam formulir n,kdimasukkan & dievaluasi dalam sel sebelumnya. Ini mensimulasikan "input baris perintah" dengan menetapkannya _(mirip dengan argumen baris perintah).

Sage Notebook ( 42 44 43)

Atau, menggunakan "input sumber" (dengan hanya x=karakter baris baru dan ditambahkan ke skor), misalnya,

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

Kedua pendekatan ini jelas merupakan spin-off dari jawaban sebelumnya oleh orang lain.

res
sumber
0

Tcl , 80 byte

proc C n\ k {proc f n {expr $n?($n)*\[f $n-1]:1}
expr [f $n]/([f $k]*[f $n-$k])}

Cobalah online!

sergiol
sumber
Pendekatan yang sangat ungolfy, 165 byte: tio.run/…
sergiol
0

Javascript, 27 byte

Pertama solusi 35-byte saya sendiri:

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

Atau, sebagai alternatif,

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

Yang pertama bekerja secara rekursif, dengan (n,k) = (n-1,k) + (n-1,k-1)aturan sederhana . Yang kedua menggunakan itu (n,k) = (n-1,k-1) * n/k.

EDIT

Saya hanya memperhatikan solusi dari Arnould dalam duplikatnya:

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

Yang merupakan 8 byte kurang dari (27 byte)

vrugtehagel
sumber
0

TI-BASIC, 16 karakter (8 byte)

Ans(1) nCr Ans(2

Input adalah daftar panjang 2 in Ans.
Output adalah hasil dari rumus yang didefinisikan di sini .

Jika solusi di atas tidak cukup, maka solusi 35 karakter (24 byte) berikut ini juga berfungsi:

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

Catatan: TI-BASIC adalah bahasa tokenized. Jumlah karakter tidak sama dengan jumlah byte.

Tau
sumber