การรวมกันทางคณิตศาสตร์


11

เขียนโปรแกรมที่รับอินพุตเช่น:

n,k

ซึ่งคำนวณ:

การรวมกันของ n และ k  (C (n, k))

แล้วพิมพ์ผลลัพธ์


ตัวอย่างตัวเลข:

การป้อนข้อมูล:

5,2

การคำนวณภายใน:

(5) / (3! x2!)

พิมพ์ออก:

10

ฉันต้องการที่จะเห็นคำตอบที่เต้นงูหลามโซลูชั่นของฉัน 65 ตัวอักษร แต่ทุกภาษายินดีต้อนรับอย่างชัดเจน

นี่คือทางออกของฉัน:

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

@Ventero คุณพูดถูกฉันหมายถึงโปรแกรม ขอโทษสำหรับเรื่องนั้น.
backus

3
โดยทั่วไปแนวคิดทางคณิตศาสตร์ขั้นพื้นฐานไม่ใช่คำถามเกี่ยวกับกอล์ฟที่ยอดเยี่ยมเพราะ J, APL, Maple, Mathematica และอื่น ๆ อีกมากมายจะสร้างมันขึ้นมานอกจากนี้ยังมีความเฉพาะเจาะจงมากขึ้นเกี่ยวกับรูปแบบอินพุตและเอาต์พุตและให้ผลลัพธ์ตัวอย่าง - ฉันไม่สามารถ บอกว่าคุณหมายถึง 5 เลือก 2 หรือ 2 เลือก 5 ที่นี่
Jesse Millikan

@Jesse ฉันได้รับความท้าทายนี้จากเว็บไซต์อื่นที่อนุญาตเฉพาะภาษาสคริปต์ที่สำคัญฉันจะจดจำคำแนะนำนี้ในอนาคต ฉันแก้ไขคำถามของฉันเพื่อลองและทำให้ความต้องการการท้าทายชัดเจนมากขึ้นแจ้งให้ฉันทราบว่ามันชัดเจนเพียงพอหรือไม่
backus

ฉันใหม่ดังนั้นเราจึงอยู่ในเรือลำเดียวกัน อย่างไรก็ตามอย่าสรุปผลลัพธ์ พวกเขาจะล้าสมัย เพียงลงคะแนนและ (ถ้าเหมาะสม) ยอมรับคำตอบ (นอกจากนี้คุณจะทำให้ผู้คนไม่มีความสุขถ้าคุณไม่สนใจคำตอบ J และ GolfScript โดยไม่มีเหตุผล)
Jesse Millikan

คำตอบ:


11

APL, 3 ไบต์

⎕!⎕

หรือสำหรับผู้ที่เบราว์เซอร์ไม่แสดงผลข้างต้นในการแสดงผล ASCII

{Quad}!{Quad}

3
การจะมีความสอดคล้องอย่างสมบูรณ์กับการป้อนข้อมูลที่คุณจะต้องทำn,k !/⌽⎕
marinus


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\{)*}/}//

Factorial เหมือนส่วนที่จะตามออกคำตอบก่อนหน้านี้


6

GolfScript 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] {*}
*"พับ" อาร์เรย์โดยใช้คำสั่งบล็อกซึ่งในกรณีนี้ทำให้ผลิตภัณฑ์ขององค์ประกอบทั้งหมด
20
หลังจากวนรอบใหญ่เสร็จสิ้นจะส่งคืนอาร์เรย์พร้อมผลลัพธ์
[20 2]
~รื้อโครงสร้างอาร์เรย์
20 2
/กอง
10


6

ทับทิม 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

Python (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

เราสามารถใช้*สำหรับการแยกวิเคราะห์อินพุตของแบบฟอร์มได้4545 78หรือไม่?
Quixotic

น่าเสียดายที่ไม่ใช่ แต่นั่นไม่ใช่*ปัญหา 4545 78ไม่ได้เป็นงูหลามแสดงออกที่ถูกต้องเพื่อจะยกระดับinput() เคล็ดลับนี้ขึ้นอยู่กับปัญหาที่เกิดขึ้นขอSyntaxError x,yหากคุณมีฟังก์ชั่นที่อ่านx yและคืนค่า tuple คุณสามารถใช้*กับสิ่งนั้นได้



3

J, 33 36

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

อักขระ 35 ตัวคืออินพุตการแยกวิเคราะห์และเอาต์พุต ตัวละครอื่น ๆ!,, คือ n เลือก k

ฉันไม่มี Windows ในการทดสอบในตอนนี้ แต่ฉันเชื่อว่ามันน่าจะใช้ได้





2

Q ( 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

Perl 6 , 25 16 ไบต์

-9 ไบต์ขอบคุณ nwellnhof

+*o&combinations

ลองออนไลน์!

ฟังก์ชั่นไม่ระบุชื่อที่ใช้ตัวเลขสองตัวและส่งกลับค่า int สิ่งนี้ใช้ในตัวcombinationsและแปลงรายการที่ส่งคืนเป็น int



@nwellnhof อาฉันไม่คิดว่าcombinationsจะใช้ตัวเลขแทนรายการ
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

Python (54)

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

เป็นหลักเช่นเดียวกับ Python หนึ่งข้างต้น แต่ฉันโกนออกสี่ไบต์โดยปล่อย

and 1

จากนิยามฟังก์ชั่น อย่างไรก็ตามผลลัพธ์นี้ในฟังก์ชันที่ส่งคืนค่า True แทนที่จะเป็น 1 ถ้า k = 0 แต่สามารถแก้ไขได้ด้วยการคูณด้วย 1 ก่อนการพิมพ์ตั้งแต่ 1 * True = 1 ดังนั้นจึงเพิ่มสองไบต์



0

Haskell (80)

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

แต่ถ้าx yอนุญาตให้ป้อนข้อมูลในรูปแบบแทนที่จะเป็นรูปแบบx,yก็จะเป็น 74 ตัวอักษร:

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


0

Python (52)

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

ปรับปรุงจากอีกสองตัวโดยใช้print+เพื่อแปลงผลลัพธ์fจากbooleanเป็นเป็นintในกรณีk==0ในกรณีที่

ยังไม่ทราบว่าจะย่อขนาดเป็น 39 ได้อย่างไรฉันสงสัยว่าพวกเขาใช้แลมบ์ดาเลยหรือเปล่า


0

(OP ระบุวิธี / รูปแบบอินพุตและเอาต์พุตแบบหลวมดังนั้นจึงเป็นที่ยอมรับได้ดังต่อไปนี้)

Sage Notebook ( 39 41 40)

ในเซลล์ปัจจุบัน

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

โดยที่อินพุตในฟอร์มn,kถูกป้อน & ประเมินในเซลล์ก่อนหน้า สิ่งนี้จำลอง "อินพุตบรรทัดคำสั่ง" โดยกำหนดให้กับ_(คล้ายกับอาร์กิวเมนต์บรรทัดรับคำสั่ง)

Sage Notebook ( 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 Ansใน
เอาท์พุทเป็นผลมาจากสูตรที่กำหนดไว้ที่นี่

หากวิธีการข้างต้นไม่พอเพียงให้ทำดังนี้ 35 chars (24 bytes) ต่อไปนี้จะทำงานด้วย:

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

หมายเหตุ: TI-BASIC เป็นภาษาโทเค็น จำนวนตัวละครทำไม่เท่ากับจำนวนไบต์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.