Zählen Sie die Anzahl der Möglichkeiten, Bälle in Behälter zu legen

9

In dieser Aufgabe erhalten Sie eine ungerade Anzahl weißer Kugeln und die gleiche Anzahl schwarzer Kugeln. Die Aufgabe besteht darin, alle Arten des Einlegens der Kugeln in Behälter zu zählen, so dass in jedem Behälter eine ungerade Anzahl jeder Farbe vorhanden ist.

Nehmen wir zum Beispiel an, wir haben 3 weiße Kugeln. Die verschiedenen Möglichkeiten sind:

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

für die zwei verschiedenen Möglichkeiten.

Wenn wir 5 weiße Kugeln haben, gibt es verschiedene Möglichkeiten:

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

Sie können die Eingabe, die eine einzelne Ganzzahl ist, beliebig übernehmen. Die Ausgabe ist nur eine einzelne Ganzzahl.

Ihr Code muss schnell genug sein, damit Sie ihn für 11 weiße Kugeln vollständig gesehen haben.

Sie können jede Sprache oder Bibliothek verwenden, die Sie mögen.


quelle
Bitte klären Sie, kann unsere Ausgabe nur die Anzahl der verschiedenen Arten sein? Das heißt, eine einzelne Zahl als Ausgabe?
Orlp
5
Ich gehe davon aus, dass dies von math.stackexchange.com/questions/2736933/… stammt. Sie sollten es @Lembik
qwr
3
Ich denke, Sie sollten das Geschwindigkeitskriterium herausnehmen oder genauer definieren. "Schnell genug" ist zu vage.
Dylnan
1
Sie wissen, dass PPCG-Benutzer so verrückt sind, dass sie lieber Geld für die Verwendung eines Supercomputers ausgeben würden, um ihn für 11 zu berechnen, als 1 Byte mehr zu benötigen? Warum also ihr Geld verschwenden? :)
user202729
1
(Anmerkung: Es ist möglich, die P-Funktion mit einer komplizierten Formel effizient zu berechnen . Möglicherweise kann diese Funktion auch mit einer geeigneten Formel berechnet werden.)
user202729

Antworten:

5

Pari / GP, 81 Bytes

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)

Für mehr Effizienz, ersetzen 1+mit 1+O(x^(n+1))+O(y^(n+1))+(der erste OBegriff allein hilft schon viel).

Probieren Sie es online aus! (frühere 86-Byte-Version mit einem Paar nicht benötigter Parens und ohne p=Abkürzung)

Alte Version, 90 Bytes

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)

Computing f(11)benötigt eine größere Stapelgröße. In der Fehlermeldung erfahren Sie, wie Sie diese erhöhen können. Es ist effizienter (aber weniger Golfy) , die beide zu ersetzen , ndie als zweites Argument scheinen prodmit (n-1)/2.

Christian Sievers
quelle
Funktioniert bis zu 13 für mich!
Ich denke das ist mit der Version mit (n-1)/2?
Christian Sievers
Ja, guter Punkt.
Glauben Sie aus Interesse, dass es möglich ist, f (500) zu berechnen?
2
Es dauert einige Minuten, um f (500) = 214621724504756565823588442604868476223315183681404
Christian Sievers
7

Python 3, 108 Bytes

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)

Listet alle Sätze rekursiv auf und stellt sicher, dass keine Duplikate erstellt werden, indem die Sätze immer in der richtigen Reihenfolge generiert werden. Ziemlich schnell, wenn mit gespeichert C = functoools.lru_cache(None)(C), aber dies ist nicht notwendig für n = 11.

Rufen Sie C(num_white, num_black)an, um Ihr Ergebnis zu erhalten. Erste paar von n:

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

So generieren Sie die Ergebnisse:

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

ZB für (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)]
orlp
quelle
Wirklich sehr nett.
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]

Probieren Sie es online aus!

Einfache Implementierung der Erzeugungsfunktion. Lang aber (etwas) effizient. O (n 4 ) Zeit, O (n 2 ) Speicher.

Das resultierende Array aenthält alle Ergebnisse aller Größen bis zu n, obwohl nur a[n][n]zurückgegeben wird.

user202729
quelle
Was berechnet Ihr Code für n aus Interesse? Wie in einem [4] [4].
Dies ist auch die bisher schnellste Lösung!
2
@Lembik a [4] [4] = Anzahl der Möglichkeiten, 4 weiße und 4 schwarze Kugeln in Behälter zu legen. Jeder Behälter hat eine ungerade Anzahl weißer Kugeln und eine ungerade Anzahl schwarzer Kugeln. Genau wie in der Definition.
user202729
1

Python 2 ,168 181 Bytes

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]

Probieren Sie es online aus!

Sonniger Patel
quelle
Dies ist ein Snippet (vorausgesetzt, es nenthält die Eingabe). Sie sollten entweder hinzufügen def f(n):oder n=input()(um es zu einer Funktion bzw. einem vollständigen Programm zu machen)
user202729
Und ... das ist Python 2, Sie können eine Registerkarte anstelle von zwei Leerzeichen verwenden. Speichert ein Byte. Das akann sein eval(`[[0]*n]*n`)(wo `steht für repr).
user202729