Policz liczbę sposobów umieszczania piłek w pojemnikach

9

W tym zadaniu otrzymujesz nieparzystą liczbę białych kulek i taką samą liczbę czarnych kulek. Zadanie polega na policzeniu wszystkich sposobów umieszczania piłek w pojemnikach, tak aby w każdym pojemniku znajdowała się nieparzysta liczba każdego koloru.

Powiedzmy, że mamy 3 białe kulki. Różne sposoby to:

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

dla dwóch różnych możliwości.

Jeśli mamy 5 białych kulek, różne sposoby to:

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

Możesz pobrać dane wejściowe, które są pojedynczymi liczbami całkowitymi, w dowolny sposób. Dane wyjściowe to tylko jedna liczba całkowita.

Twój kod musi być wystarczająco szybki, abyś mógł go zobaczyć dla 11 białych kulek.

Możesz użyć dowolnego języka lub biblioteki.


źródło
Wyjaśnij, czy nasze wyniki mogą być tylko różnymi sposobami? To znaczy, jedna liczba jako wynik?
lub
5
Zakładam, że pochodzi z math.stackexchange.com/questions/2736933/ ... Powinieneś to zacytować @Lembik
qwr
3
Myślę, że powinieneś wziąć pod uwagę kryterium prędkości lub sprecyzować je. „Wystarczająco szybki” jest zbyt niejasne.
dylnan
1
Wiesz, że użytkownicy PPCG są na tyle szaleni, że woleliby wydawać pieniądze na użycie superkomputera do obliczenia go na 11, niż biorąc 1 bajt więcej? Po co więc marnować pieniądze? :)
user202729,
1
(uwaga: Możliwe jest wydajne obliczenie funkcji P za pomocą skomplikowanej formuły . Możliwe jest również obliczenie tej funkcji za pomocą odpowiedniej formuły.)
202729

Odpowiedzi:

5

Pari / GP, 81 bajtów

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)

Dla większej efektywności, wymienić 1+z 1+O(x^(n+1))+O(y^(n+1))+(pierwszy Osam termin już pomaga dużo).

Wypróbuj online! (wcześniejsza wersja 86-bajtowa z parą niepotrzebnych parenów i bez p=skrótu)

Stara wersja, 90 bajtów

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)

Komputer f(11)wymaga większego rozmiaru stosu, komunikat o błędzie powie ci, jak go zwiększyć. To jest bardziej wydajny (ale mniej Golfy) wymienić dwie n, które pojawiają się jako drugie argumenty do prodz (n-1)/2.

Christian Sievers
źródło
Działa dla mnie do 13 lat!
Chyba tak jest z wersją używającą (n-1)/2?
Christian Sievers
Tak, dobra uwaga.
Czy poza zainteresowaniem uważasz, że można obliczyć f (500)?
2
Obliczenie f (500) = 214621724504756565823588442604868476223315183681404 zajmuje kilka minut
Christian Sievers
7

Python 3, 108 bajtów

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)

Rekurencyjnie wylicza wszystkie zestawy, upewniając się, że nie zostaną duplikowane, zawsze generując zestawy w kolejności. Racjonalnie szybki, gdy zapamiętujesz go C = functoools.lru_cache(None)(C), ale nie jest to konieczne n = 11.

Zadzwoń, C(num_white, num_black)aby uzyskać wynik. Pierwsza para n:

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

Aby wygenerować wyniki:

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

Np. Dla (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
źródło
Naprawdę bardzo ładnie.
2

Python 3 , 180 172 bajtów

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]

Wypróbuj online!

Prosta implementacja funkcji generującej. Długi, ale (nieco) wydajny. Czas O (n 4 ), pamięć O (n 2 ).

Powstała tablica azawiera wszystkie wyniki o wszystkich rozmiarach do n, chociaż a[n][n]zwracana jest tylko .

użytkownik202729
źródło
Co twój kod oblicza dla nawet n, poza zainteresowaniem? Jak w [4] [4].
To najszybsze jak dotąd rozwiązanie!
2
@Lembik a [4] [4] = Liczba sposobów na umieszczenie 4 białych i 4 czarnych kulek w pojemnikach, każdy pojemnik ma nieparzystą liczbę białych kulek i nieparzystą liczbę czarnych kulek. Dokładnie jak w definicji.
user202729,
1

Python 2 ,168 181 bajtów

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]

Wypróbuj online!

Sunny Patel
źródło
To jest fragment kodu (zakłada się, że nzawiera dane wejściowe) Powinieneś dodać def f(n):lub n=input()(aby uczynić go funkcją / pełnego programu).
18.04.2018
I ... to jest Python 2, możesz użyć tabulacji zamiast dwóch spacji. Zapisuje bajt. aMoże być eval(`[[0]*n]*n`)(gdzie `skrót repr).
user202729,