Conte o número de maneiras de colocar bolas em caixas

9

Nesta tarefa, você recebe um número ímpar de bolas brancas e o mesmo número de bolas pretas. A tarefa é contar todas as maneiras de colocar as bolas em caixas para que em cada caixa haja um número ímpar de cada cor.

Por exemplo, digamos que temos 3 bolas brancas. As diferentes maneiras são:

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

para as duas possibilidades diferentes.

Se temos 5 bolas brancas, as diferentes maneiras são:

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

Você pode pegar a entrada, que é um único inteiro, da maneira que desejar. A saída é apenas um único número inteiro.

Seu código deve ser rápido o suficiente para que você o veja completo por 11 bolas brancas.

Você pode usar qualquer idioma ou biblioteca que desejar.


fonte
Por favor, esclareça, nossa saída pode ser apenas o número de maneiras diferentes? Ou seja, um único número como saída?
orlp
5
Eu suponho que isso é de math.stackexchange.com/questions/2736933/… Você deve citá-lo @Lembik
qwr
3
Eu acho que você deve adotar o critério de velocidade ou torná-lo mais específico. "Rápido o suficiente" é muito vago.
dylnan
11
Você sabe que os usuários do PPCG são loucos o suficiente para preferir gastar dinheiro usando um supercomputador para computá-lo por 11 do que usar mais 1 byte? Então, por que desperdiçar seu dinheiro? :)
usar o seguinte comando
11
(Nota: É possível calcular a função P de forma eficiente com uma fórmula complicada .. Pode ser possível calcular esta função também, com uma fórmula apropriada)
user202729

Respostas:

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)

Para obter mais eficiência, substitua 1+por 1+O(x^(n+1))+O(y^(n+1))+(o primeiro Otermo por si só já ajuda bastante).

Experimente online! (versão anterior de 86 bytes com um par de letras desnecessárias e sem a p=abreviação)

Versão antiga, 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)

A computação f(11)precisa de um tamanho de pilha maior, a mensagem de erro informará como aumentá-lo. É mais eficiente (mas menos eficiente) substituir os dois nque aparecem como segundos argumentos prodpor (n-1)/2.

Peneiradores cristãos
fonte
Funciona até 13 para mim!
Eu acho que é com a versão usando (n-1)/2?
Christian Sievers
Sim, bom argumento.
Por falta de interesse, você acha que é possível calcular f (500)?
2
Demora alguns minutos para calcular 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)

Enumera recursivamente todos os conjuntos, certificando-se de não obter duplicatas sempre gerando os conjuntos em ordem. Razoavelmente rápido quando memorizado usando C = functoools.lru_cache(None)(C), mas isso não é necessário n = 11.

Ligue C(num_white, num_black)para obter seu resultado. Primeiro par de n:

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

Para gerar os resultados:

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

Por exemplo, para (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
fonte
Muito bom mesmo.
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]

Experimente online!

Implementação direta da função geradora. Longo, mas (um pouco) eficiente. O (n 4 ) tempo, O (n 2 memória ).

A matriz resultante acontém todos os resultados de todos os tamanhos n, embora apenas a[n][n]seja retornada.

user202729
fonte
O que seu código calcula para n mesmo, sem interesse? Como em um [4] [4].
Esta é a solução mais rápida até agora!
2
@Lembik a [4] [4] = Número de maneiras de colocar 4 bolas brancas e 4 bolas pretas em caixas, cada caixa tem um número ímpar de bolas brancas e um número ímpar de bolas pretas. Exatamente como na definição.
usar o seguinte comando
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]

Experimente online!

Sunny Patel
fonte
Este é um trecho (assume ncontém a entrada) Você deve ou adicionar def f(n):ou n=input()(para torná-lo uma função / resp programa completo.)
user202729
E ... este é o Python 2, você pode usar uma guia em vez de dois espaços. Salva um byte. O apode ser eval(`[[0]*n]*n`)(onde `significa repr).
usar o seguinte comando