ボールをビンに入れる方法の数を数える


9

このタスクでは、奇数の白いボールと同じ数の黒いボールが与えられます。タスクは、各ビンに各色の奇数があるように、ボールをビンに入れるすべての方法を数えることです。

たとえば、3つの白いボールがあるとします。異なる方法は次のとおりです。

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

2つの異なる可能性のために。

5つの白いボールがある場合、さまざまな方法があります。

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

単一の整数である入力は、好きな方法で取得できます。出力は単一の整数です。

あなたのコードは、11個の白いボールが完全に見えるように十分に高速でなければなりません。

任意の言語またはライブラリを使用できます。


明確にしてください、私たちの出力はさまざまな方法の数にすぎませんか?つまり、出力として単一の数値ですか?
orlp

5
私はこれがmath.stackexchange.com/questions/2736933/からのものであると思います...引用するには@Lembik
qwr

3
速度の基準を外すか、もっと具体的にすべきだと思います。「十分速い」は曖昧すぎる。
ディルナン

1
PPCGユーザーは、1バイトを増やすよりも、スーパーコンピューターを使用してそれを計算するためにお金を費やすのに十分夢中になっていることを知っていますか?それでなぜ彼らのお金を無駄にするのですか?:)
user202729

1
(備考:複雑な数式でP関数を効率的に計算することは可能です。適切な数式でこの関数も計算できる可能性があります。)
user202729

回答:


5

パリ/ 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単独の用語は、すでに多くのことができます)。

オンラインでお試しください!(不要な括弧のペアがあり、p=省略形のない以前の86バイトバージョン)

古いバージョン、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)にはより大きなスタックサイズが必要です。エラーメッセージはそれを増やす方法を示します。これは、2つ交換し、より効率的な(あまりgolfy)ですn2番目の引数として現れる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の3180の 172バイト

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)メモリ。

結果の配列にan、のみa[n][n]が返されますが、までのすべてのサイズのすべての結果が含まれます。


あなたのコードは、興味のないところで、nに対して偶数を計算しますか?a [4] [4]のように。

これも、これまでで最速のソリューションです。

2
@Lembik a [4] [4] = 4つの白いボールと4つの黒いボールをビンに入れる方法の数。各ビンには、奇数の白いボールと奇数の黒いボールがあります。まさに定義のように。
user202729

1

Python 2168 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]

オンラインでお試しください!


これはスニペットです(n入力が含まれていることを前提としています)def f(n):またはn=input()(関数/完全なプログラムの
応答

そして...これはPython 2です。2つのスペースの代わりにタブを使用できます。バイトを保存します。するaことができますeval(`[[0]*n]*n`)(はの`略ですrepr)。
user202729
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.