Comptez le nombre de façons de mettre des balles dans des bacs

9

Dans cette tâche, vous obtenez un nombre impair de boules blanches et le même nombre de boules noires. La tâche consiste à compter toutes les façons de mettre les balles dans des bacs de sorte que dans chaque bac, il y ait un nombre impair de chaque couleur.

Par exemple, disons que nous avons 3 boules blanches. Les différentes manières sont:

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

pour les deux possibilités différentes.

Si nous avons 5 boules blanches, les différentes manières sont:

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

Vous pouvez prendre l'entrée, qui est un entier unique, comme vous le souhaitez. La sortie n'est qu'un seul entier.

Votre code doit être assez rapide pour que vous l'ayez vu complet pour 11 boules blanches.

Vous pouvez utiliser n'importe quelle langue ou bibliothèque que vous aimez.


la source
Veuillez clarifier, notre sortie peut-elle être uniquement le nombre de façons différentes? Autrement dit, un seul numéro en sortie?
orlp
5
Je suppose que cela vient de math.stackexchange.com/questions/2736933/… Vous devriez le citer @Lembik
qwr
3
Je pense que vous devriez supprimer le critère de vitesse ou le rendre plus spécifique. "Assez vite" est trop vague.
dylnan
1
Vous savez que les utilisateurs de PPCG sont assez fous pour qu'ils préfèrent dépenser de l'argent pour utiliser un supercalculateur pour le calculer pour 11 plutôt que de prendre 1 octet de plus? Alors pourquoi gaspiller leur argent? :)
user202729
1
(remarque: il est possible de calculer efficacement la fonction P avec une formule compliquée . Il peut aussi être possible de calculer cette fonction, avec une formule appropriée.)
user202729

Réponses:

5

Pari / GP, 81 octets

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)

Pour plus d'efficacité, remplacez 1+par 1+O(x^(n+1))+O(y^(n+1))+(le premier Oterme seul aide déjà beaucoup).

Essayez-le en ligne! (version antérieure de 86 octets avec une paire de parens inutiles et sans l' p=abréviation)

Ancienne version, 90 octets

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)

L'informatique a f(11)besoin d'une plus grande taille de pile, le message d'erreur vous indiquera comment l'augmenter. Il est plus efficace (mais moins golfique) de remplacer les deux nqui apparaissent comme deuxièmes arguments prodavec (n-1)/2.

Christian Sievers
la source
Fonctionne jusqu'à 13 pour moi!
Je suppose que c'est avec la version utilisant (n-1)/2?
Christian Sievers
Oui, bon point.
Par intérêt, pensez-vous qu'il est possible de calculer f (500)?
2
Il faut quelques minutes pour calculer f (500) = 214621724504756565823588442604868476223315183681404
Christian Sievers
7

Python 3, 108 octets

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)

Énumère récursivement tous les ensembles, en veillant à ne pas obtenir de doublons en générant toujours les ensembles dans l'ordre. Raisonnablement rapide lorsqu'il est mémorisé en utilisant C = functoools.lru_cache(None)(C), mais ce n'est pas nécessaire pour n = 11.

Appelez C(num_white, num_black)pour obtenir votre résultat. Premier couple de n:

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

Pour générer les résultats:

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

Par exemple pour (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
la source
Très beau effectivement.
2

Python 3 , 180 172 octets

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]

Essayez-le en ligne!

Implémentation simple de la fonction de génération. Long mais (un peu) efficace. O (n 4 ) temps, O (n 2 ) mémoire.

Le tableau résultant acontient tous les résultats de toutes les tailles jusqu'à n, bien que seul a[n][n]soit renvoyé.

user202729
la source
Que calcule votre code pour même n, par intérêt? Comme dans un [4] [4].
C'est la solution la plus rapide jusqu'à présent!
2
@Lembik a [4] [4] = Nombre de façons de mettre 4 boules blanches et 4 boules noires dans des bacs, chaque bac a un nombre impair de boules blanches et un nombre impair de boules noires. Exactement comme dans la définition.
user202729
1

Python 2 ,168 181 octets

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]

Essayez-le en ligne!

Sunny Patel
la source
Ceci est un extrait (suppose qu'il ncontient l'entrée) Vous devez soit ajouter def f(n):soit n=input()(pour en faire une fonction / un programme complet resp.)
user202729
Et ... c'est Python 2, vous pouvez utiliser un onglet au lieu de deux espaces. Enregistre un octet. Le apeut être eval(`[[0]*n]*n`)(où `signifie repr).
user202729