Conta il numero di modi per mettere le palle nei cassonetti


9

In questo compito ti viene dato un numero dispari di palline bianche e lo stesso numero di palline nere. Il compito è contare tutti i modi di mettere le palline nei contenitori in modo che in ogni cestino ci sia un numero dispari di ciascun colore.

Ad esempio, supponiamo di avere 3 palline bianche. I diversi modi sono:

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

per le due diverse possibilità.

Se abbiamo 5 palline bianche i diversi modi sono:

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

Puoi prendere l'input, che è un singolo numero intero, nel modo che preferisci. L'output è solo un singolo numero intero.

Il tuo codice deve essere abbastanza veloce da averlo visto completo per 11 palline bianche.

È possibile utilizzare qualsiasi lingua o libreria che ti piace.


Si prega di chiarire, il nostro output può essere solo il numero di modi diversi? Cioè, un singolo numero come output?
orlp,

5
Presumo che questo provenga da math.stackexchange.com/questions/2736933/… Dovresti citarlo @Lembik
qwr

3
Penso che dovresti eliminare il criterio di velocità o renderlo più specifico. "Abbastanza veloce" è troppo vago.
dylnan,

1
Sai che gli utenti di PPCG sono abbastanza pazzi che preferirebbero spendere soldi per usare un supercomputer per calcolarlo per 11 piuttosto che prendere 1 byte in più? Quindi perché sprecare i loro soldi? :)
user202729,

1
(nota: è possibile calcolare la funzione P in modo efficiente con una formula complicata . Potrebbe essere possibile calcolare anche questa funzione, con una formula adatta.)
user202729

Risposte:


5

Pari / GP, 81 byte

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)

Per una maggiore efficienza, sostituisci 1+con 1+O(x^(n+1))+O(y^(n+1))+(il primo Otermine da solo aiuta già molto).

Provalo online! (versione precedente di 86 byte con una coppia di parentesi non necessarie e senza p=abbreviazione)

Vecchia versione, 90 byte

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)

Il calcolo ha f(11)bisogno di una dimensione dello stack più grande, il messaggio di errore ti dirà come aumentarlo. È più efficiente (ma meno golfoso) sostituire i due nche appaiono come secondi argomenti prodcon (n-1)/2.


Funziona fino a 13 per me!

Immagino che sia con la versione usando (n-1)/2?
Christian Sievers,

Sì, buon punto.

Per interesse, pensi che sia possibile calcolare f (500)?

2
Sono necessari alcuni minuti per calcolare f (500) = 214621724504756565823588442604868476223315183681404
Christian Sievers,

7

Python 3, 108 byte

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 ricorsivamente tutti i set, assicurandosi di non ottenere duplicati generando sempre i set in ordine. Abbastanza veloce se memorizzato usando C = functoools.lru_cache(None)(C), ma questo non è necessario per n = 11.

Chiama C(num_white, num_black)per ottenere il tuo risultato. Prima coppia di n:

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

Per generare i risultati:

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

Ad esempio per (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)]

Davvero molto bello.

2

Python 3 , 180 172 byte

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]

Provalo online!

Implementazione diretta della funzione di generazione. Lungo ma (in qualche modo) efficiente. O (n 4 ) tempo, O (n 2 ) memoria.

L'array risultante acontiene tutti i risultati di tutte le dimensioni fino a n, anche se a[n][n]viene restituito solo .


Cosa calcola il tuo codice anche per n, per interesse? Come in un [4] [4].

Questa è la soluzione più veloce finora!

2
@Lembik a [4] [4] = Numero di modi per mettere 4 palline bianche e 4 palline nere in bidoni, ogni bidone ha un numero dispari di palline bianche e un numero dispari di palline nere. Esattamente come nella definizione.
user202729

1

Python 2 ,168 181 byte

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]

Provalo online!


Questo è uno snippet (presuppone che ncontenga l'input) Dovresti aggiungere def f(n):o n=input()(per renderlo una funzione / risp.
Completo del

E ... questo è Python 2, puoi usare una scheda invece di due spazi. Salva un byte. La apuò essere eval(`[[0]*n]*n`)(dove `sta per repr).
user202729,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.