Cuente la cantidad de formas de poner bolas en contenedores

9

En esta tarea se le da un número impar de bolas blancas y el mismo número de bolas negras. La tarea es contar todas las formas de poner las bolas en contenedores para que en cada contenedor haya un número impar de cada color.

Por ejemplo, digamos que tenemos 3 bolas blancas. Las diferentes formas son:

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

por las dos posibilidades diferentes.

Si tenemos 5 bolas blancas, las diferentes formas son:

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

Puede tomar la entrada, que es un número entero único, de la forma que desee. La salida es solo un entero entero.

Su código debe ser lo suficientemente rápido para que lo haya visto completo para 11 bolas blancas.

Puede usar cualquier idioma o biblioteca que desee.


fuente
Por favor aclare, ¿puede nuestra salida ser solo el número de formas diferentes? Es decir, ¿un solo número como salida?
orlp
55
Supongo que esto es de math.stackexchange.com/questions/2736933/… Deberías citarlo @Lembik
qwr
3
Creo que debería sacar el criterio de velocidad o hacerlo más específico. "Lo suficientemente rápido" es demasiado vago.
dylnan
1
¿Sabía que los usuarios de PPCG están lo suficientemente locos como para preferir gastar dinero en usar una supercomputadora para calcularlo por 11 que tomar 1 byte más? Entonces, ¿por qué malgastar su dinero? :)
user202729
1
(observación: es posible calcular la función P de manera eficiente con una fórmula complicada . También es posible calcular esta función, con una fórmula adecuada.)
user202729

Respuestas:

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 mayor eficiencia, reemplace 1+con 1+O(x^(n+1))+O(y^(n+1))+(el primer Otérmino solo ya ayuda mucho).

Pruébalo en línea! (versión anterior de 86 bytes con un par de parens innecesarios y sin la p=abreviatura)

Versión anterior, 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)

La informática f(11)necesita un tamaño de pila más grande, el mensaje de error le indicará cómo aumentarlo. Es más eficiente (pero menos golfoso) reemplazar los dos nque aparecen como segundos argumentos prodcon (n-1)/2.

Christian Sievers
fuente
¡Funciona hasta 13 para mí!
Supongo que es con la versión usando (n-1)/2?
Christian Sievers
Si, buen punto.
Por interés, ¿crees que es posible calcular f (500)?
2
Se tarda unos minutos en 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 los conjuntos, asegurándose de no obtener duplicados generando siempre los conjuntos en orden. Razonablemente rápido cuando se memoriza usando C = functoools.lru_cache(None)(C), pero esto no es necesario n = 11.

Llame C(num_white, num_black)para obtener su resultado. Primer 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 generar los 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 ejemplo 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
fuente
Muy bueno de verdad.
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]

Pruébalo en línea!

Implementación directa de la función generadora. Largo pero (algo) eficiente. O (n 4 ) tiempo, O (n 2 ) memoria.

La matriz resultante acontiene todos los resultados de todos los tamaños hasta n, aunque solo a[n][n]se devuelve.

usuario202729
fuente
¿Qué calcula su código para incluso n, fuera de interés? Como en un [4] [4].
¡Esta es la solución más rápida hasta ahora también!
2
@Lembik a [4] [4] = Número de formas de colocar 4 bolas blancas y 4 bolas negras en contenedores, cada contenedor tiene un número impar de bolas blancas y un número impar de bolas negras. Exactamente como en la definición.
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]

Pruébalo en línea!

Sunny Patel
fuente
Este es un fragmento (se supone que ncontiene la entrada) Debe agregar def f(n):o n=input()(para que sea una función / programa completo resp.)
usuario202729
Y ... este es Python 2, puedes usar una pestaña en lugar de dos espacios. Guarda un byte. El apuede ser eval(`[[0]*n]*n`)(donde `significa repr).
user202729