นับจำนวนวิธีในการวางลูกบอลลงในถังขยะ


9

ในภารกิจนี้คุณจะได้รับลูกบอลสีขาวจำนวนคี่และลูกบอลสีดำจำนวนเดียวกัน ภารกิจคือการนับวิธีการทั้งหมดของการวางลูกบอลลงในถังขยะเพื่อให้ในแต่ละถังขยะมีจำนวนคี่ของแต่ละสี

ตัวอย่างเช่นสมมติว่าเรามีลูกบอลสีขาว 3 ลูก วิธีที่แตกต่างคือ:

(wwwbbb)
(wb)(wb)(wb)

สำหรับสองโอกาสที่แตกต่างกัน

หากเรามีลูกบอลสีขาว 5 ลูกวิธีที่ต่างกันคือ:

(wwwwwbbbbb)
(wwwbbb)(wb)(wb)
(wwwb)(wbbb)(wb)
(wb)(wb)(wb)(wb)(wb)

คุณสามารถรับอินพุตซึ่งเป็นจำนวนเต็มเดียวในแบบที่คุณต้องการ ผลลัพธ์เป็นเพียงจำนวนเต็มเดียว

รหัสของคุณจะต้องเร็วพอเพื่อให้คุณเห็นรหัสสีขาว 11 ลูก

คุณสามารถใช้ภาษาหรือไลบรารีที่คุณต้องการ


โปรดอธิบายว่าผลลัพธ์ของเราเป็นเพียงวิธีที่แตกต่างกันหรือไม่ นั่นคือจำนวนเดียวเป็นเอาท์พุท?
orlp

5
ผมถือว่านี้เป็นจากmath.stackexchange.com/questions/2736933/...คุณควรอ้างอิงมัน @Lembik
qwr

3
ฉันคิดว่าคุณควรทำตามเกณฑ์ความเร็วหรือทำให้เฉพาะเจาะจงมากขึ้น "เร็วพอ" คลุมเครือเกินไป
dylnan

1
คุณรู้หรือไม่ว่าผู้ใช้ PPCG นั้นคลั่งไคล้มากพอที่จะใช้เงินในการใช้ซูเปอร์คอมพิวเตอร์เพื่อคำนวณ 11 ตัวแทนที่จะใช้ 1 ไบต์มากกว่านี้? เหตุใดจึงต้องเสียเงิน? :)
user202729

1
(หมายเหตุ: เป็นไปได้ในการคำนวณฟังก์ชัน P อย่างมีประสิทธิภาพด้วยสูตรที่ซับซ้อนคุณอาจคำนวณฟังก์ชันนี้ได้เช่นกันด้วยสูตรที่เหมาะสม)
user202729

คำตอบ:


5

Pari / GP, 81 ไบต์

p=polcoeff;f(n)=p(p(prod(i=1,n,prod(j=1,n,1+(valuation(i/j,2)==0)*x^i*y^j)),n),n)

เพื่อประสิทธิภาพมากขึ้นแทนที่1+ด้วย1+O(x^(n+1))+O(y^(n+1))+( Oเทอมแรกเพียงลำพังช่วยได้มากแล้ว)

ลองออนไลน์! (เวอร์ชัน 86 ไบต์ก่อนหน้านี้ที่มี parens ที่ไม่จำเป็นและไม่มีp=ตัวย่อ)

รุ่นเก่า 90 ไบต์

f(n)=polcoeff(polcoeff(taylor(1/prod(i=0,n,prod(j=0,n,1-x^(2*i+1)*y^(2*j+1))),x,n+1),n),n)

คอมพิวเตอร์f(11)ต้องการขนาดสแต็คที่ใหญ่กว่าข้อความแสดงข้อผิดพลาดจะบอกวิธีเพิ่มมัน มีประสิทธิภาพมากขึ้น (แต่ไม่ค่อยเล่นกอล์ฟ) เพื่อแทนที่ทั้งสองnที่ปรากฏเป็นอาร์กิวเมนต์ที่สองprod(n-1)/2มี


ทำงานได้ถึง 13 สำหรับฉัน!

ฉันเดาว่าเป็นรุ่นที่ใช้(n-1)/2หรือไม่
Christian Sievers

ใช่จุดดี

คุณคิดว่าเป็นไปได้หรือไม่ที่จะคำนวณ f (500)

2
ใช้เวลาไม่กี่นาทีในการคำนวณ f (500) = 214621724504756565823588442604868476223315183681404
Christian Sievers

7

Python 3, 108 ไบต์

C=lambda l,r,o=():((l,r)>=o)*l*r%2+sum(C(l-x,r-y,(x,y))for x in range(1,l,2)for y in range(1,r,2)if(x,y)>=o)

ระบุชุดซ้ำทั้งหมดซ้ำอย่าให้ซ้ำโดยสร้างชุดตามลำดับ เร็วพอสมควรเมื่อใช้การบันทึกความจำC = functoools.lru_cache(None)(C)แต่ไม่จำเป็นสำหรับn = 11แต่นี้ไม่ได้เป็นสิ่งที่จำเป็นสำหรับ

โทรC(num_white, num_black)มารับผลของคุณ คู่แรกของn:

1: 1
3: 2
5: 4
7: 12
9: 32
11: 85
13: 217
15: 539
17: 1316
19: 3146
21: 7374

เพื่อสร้างผลลัพธ์:

def odd_parts(l, r, o=()):
    if l % 2 == r % 2 == 1 and (l, r) >= o:
        yield [(l, r)]

    for nl in range(1, l, 2):
        for nr in range(1, r, 2):
            if (nl, nr) < o: continue
            for t in odd_parts(l - nl, r - nr, (nl, nr)):
                yield [(nl, nr)] + t

เช่นสำหรับ (7, 7):

[(7, 7)]
[(1, 1), (1, 1), (5, 5)]
[(1, 1), (1, 1), (1, 1), (1, 1), (3, 3)]
[(1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1)]
[(1, 1), (1, 1), (1, 1), (1, 3), (3, 1)]
[(1, 1), (1, 3), (5, 3)]
[(1, 1), (1, 5), (5, 1)]
[(1, 1), (3, 1), (3, 5)]
[(1, 1), (3, 3), (3, 3)]
[(1, 3), (1, 3), (5, 1)]
[(1, 3), (3, 1), (3, 3)]
[(1, 5), (3, 1), (3, 1)]

ดีมากจริงๆ

2

Python 3 , 180 172 bytes

def f(n):
 r=range;N=n+1;a=[N*[0]for _ in r(N)];R=r(1,N,2);a[0][0]=1
 for i in R:
  for j in R:
   for k in r(N-i):
    for l in r(N-j):a[k+i][l+j]+=a[k][l]
 return a[n][n]

ลองออนไลน์!

การใช้งานฟังก์ชั่นการสร้างที่ตรงไปตรงมา ยาว แต่มีประสิทธิภาพ เวลา O (n 4 ), หน่วยความจำO (n 2 )

อาร์เรย์ที่เป็นผลลัพธ์aประกอบด้วยผลลัพธ์ทั้งหมดของทุกขนาดจนถึงnแม้ว่าจะa[n][n]ถูกส่งคืนเท่านั้น


รหัสของคุณคำนวณอะไรสำหรับแม้แต่ n จากความสนใจ? เช่นเดียวกับใน [4] [4]

นี่คือทางออกที่เร็วที่สุดเช่นกัน!

2
@Lembik a [4] [4] = จำนวนวิธีในการใส่ลูกบอลสีขาว 4 ลูกและลูกบอลสีดำ 4 ลูกลงในถังขยะแต่ละถังมีลูกบอลสีขาวจำนวนหนึ่งและลูกบอลสีดำเป็นจำนวนคี่ Exacly เช่นเดียวกับใน defintion
user202729

1

งูหลาม 2 ,168 181 ไบต์

from itertools import*
r,p=range,product
def f(n):
 a,R=eval(`[[0]*n]*n`),r(1,n,2);a[0][0]=1
 for i,j in p(R,R):
  for k,l in p(r(n-i),r(n-j)):a[k+i][l+j]+=a[k][l]
 return a[-1][-1]

ลองออนไลน์!

  • ขึ้นอยู่กับคำตอบของ user202729
  • แก้ไข:ทำให้เป็นฟังก์ชันอิสระ
  • ที่บันทึกไว้ 2 ไบต์ขอบคุณที่user202729

นี่คือตัวอย่าง (สมมติว่าnมีอินพุต) คุณควรจะเพิ่มdef f(n):หรือn=input()(เพื่อให้เป็นฟังก์ชั่น / โปรแกรมเต็มรูปแบบ resp)
user202729

และ ... นี่คือ Python 2 คุณสามารถใช้แท็บแทนสองช่องว่าง บันทึกเป็นไบต์ aสามารถeval(`[[0]*n]*n`)(ที่`ย่อมาrepr)
user202729
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.