Permutazioni con oggetti indistinguibili


12

Dato un elenco di numeri interi, genera il numero di permutazioni degli interi, con permutazioni indistinguibili contate una volta. Se ci sono nnumeri interi e ogni gruppo di numeri indistinguibili ha lunghezza n_i, questo èn! / (n_1! * n_2! * ...)

Regole

  • L'input sarà una forma di elenco come argomento di una funzione o del programma con da 1 a 12 numeri interi non negativi.

  • L'output stampa o restituisce il numero di permutazioni come descritto sopra.

  • Nessuna scappatoia standard o funzioni integrate (generazione di permutazioni, combinazioni, ecc.). I fattoriali sono ammessi.

Casi test

ingressi:

1, 3000, 2, 2, 8
1, 1, 1
2, 4, 3, 2, 3, 4, 4, 4, 4, 4, 1, 1

Uscite:

60
1
83160

quando dici che non ci sono builtin, questo include ciò che ho fatto quando ho usato un builtin per generare tutte le permutazioni?
Maltysen,

1
Questo sembra in gran parte uguale a Calcola il coefficiente multinomiale . Il conteggio di voci identiche per l'input rende sufficientemente diverso da non essere un duplicato?
xnor

@xnor bene qui devi davvero contare i duplicati, quindi non è così semplice suppongo. L'altro è piuttosto semplice inserire valori.
qwr

@Maltysen purtroppo sì, dovrò aggiornare la domanda
qwr

1
Sì, lo è, anche se non dovrebbe fare la differenza per quanto posso immaginare
qwr

Risposte:


6

Python, 48 byte

f=lambda l:l==[]or len(l)*f(l[1:])/l.count(l[0])

Un'implementazione ricorsiva.

Nella formula, n! / (n_1! * n_2! * ...)se rimuoviamo il primo elemento (diciamo che è 1), il numero di permutazione per gli n-1elementi rimanenti è

(n-1)! / ((n_1-1)! * n_2! * ...) ==
n! / n / (n_1! / n_1! * n_2! * ...) == 
n/n_1 * (n! / (n_1! * n_2! * ...)`)

Quindi, otteniamo la risposta moltiplicando per n/n1, la frazione reciproca degli elementi che eguaglia il primo, per il risultato ricorsivo per il resto dell'elenco. L'elenco vuoto fornisce il caso base di 1.


Perché non metti /l.count(l[0])alla fine? Quindi non hai bisogno di quel punto fluttuante icky.
feersum

4

MATL , 14 13 12 byte

fpGu"@G=s:p/

Provalo online!

Spiegazione

L'approccio è molto simile a quello nella risposta di @Adnan .

f       % Take input implicitly. Push array of indices of nonzero entries.
        % This gives [1 2 ... n] where n is input length.
p       % Product (compute factorial)
Gu      % Push input. Array of its unique elements
"       % For each of those unique values
  @     %   Push unique value of current iteration
  G=s   %   Number of times (s) it's present (=) in the input (G)
  :p    %   Range, product (compute factorial)
  /     %   Divide
        % End for each implicitly. Display implicitly

3

05AB1E , 15 14 13 byte

Codice:

D©g!rÙv®yQO!/

Spiegazione:

               # implicit input
D©             # duplicate and save a copy to register
  g!           # factorial of input length (total nr of permutations without duplicates)
    rÙv        # for each unique number in input
       ®yQO!   # factorial of number of occurances in input
            /  # divide total nr of permutations by this
               # implicit output

Utilizza la codifica CP-1252 .

Provalo online! .


2

JavaScript (ES6), 64 61 byte

a=>a.sort().map((x,i)=>r=r*++i/(x-y?(y=x,c=1):++c),y=r=-1)|-r

Utilizza la formula fornita, tranne che per calcolare ciascun fattoriale in modo incrementale (quindi, ad esempio, per r=r*++iconfermare efficacemente n!).

Modifica: Inizialmente ho accettato qualsiasi numero finito ma ho salvato 3 byte quando @ user81655 ha sottolineato che avevo solo bisogno di supportare numeri interi positivi (anche se in realtà accetto numeri interi non negativi).


r*=++i/(x-y?(y=x,c=1):++c),y=r=-1)|-r?
user81655

@ user81655 Ah, non avevo letto abbastanza bene la domanda e ho trascurato che potevo fare affidamento sul fatto che i valori fossero numeri interi positivi. Non mi piace il *=pensiero poiché introduce errori di arrotondamento.
Neil,

2

Pyth, 11 byte

/.!lQ*F/V._

Suite di test

Utilizza la formula standard n! / (count1! * count2! * ...), tranne per il fatto che i fattoriali dei conteggi si trovano contando quante volte ogni elemento si presenta nel prefisso che porta a quello, quindi moltiplicando tutti questi numeri insieme.

Spiegazione:

/.!lQ*F/V._
/.!lQ*F/V._QQ    Implicit variable introduction.
                 Q = eval(input())
         ._Q     Form all prefixes of the input.
       /V   Q    Count how many times each element occurs in the prefix
                 ending with that element.
     *F          Fold on multiplication - take the product.
 .!lQ            Take the factorial of the input length
/                Divide.


1

Rubino, 75 74 byte

Vorrei che il Mathmodulo di Ruby avesse una funzione fattoriale, quindi non ho dovuto costruirne uno mio.

->l{f=->x{x<2?1:x*f[x-1]};l.uniq.map{|e|f[l.count e]}.inject f[l.size],:/}

1

CJam, 17 byte

q~_,\$e`0f=+:m!:/

Provalo qui.

Spiegazione

q~   e# Read input and evaluate.
_,   e# Duplicate and get length.
\$   e# Swap with other copy and sort it.
e`   e# Run-length encode. Since the list is sorted, this tallies the numbers.
0f=  e# Select the tally of each number.
+    e# Prepend the length of the input.
:m!  e# Compute the factorial of each number in the list.
:/   e# Fold division over it, which divides each factorial of a tally into
     e# the factorial of the length.

1

Gelatina, 8 byte

W;ĠL€!:/

Provalo online!

W;ĠL€!:/ example input:             [1, 3000, 2, 2, 8]
W        wrap:                      [[1, 3000, 2, 2, 8]]
  Ġ      group index by appearance: [[1], [3, 4], [5], [2]]
 ;       concatenate:               [[1, 3000, 2, 2, 8], [1], [3, 4], [5], [2]]
   L€    map by length:             [5, 1, 2, 1, 1]
     !   [map by] factorial:        [120, 1, 2, 1, 1]
      :/ reduce by division:        120÷1÷2÷1÷1 = 60

1

J, 13 byte

#(%*/)&:!#/.~

uso

   f =: #(%*/)&:!#/.~
   f 1 3000 2 2 8
60
   f 1 1 1
1
   f 2 4 3 2 3 4 4 4 4 4 1 1
83160

Spiegazione

#(%*/)&:!#/.~  Input: A
         #/.~  Partition A by equal values and get the size of each, these are the tallies
#              Get the size of A
      &:!      Take the factorial of both the size and the tallies
   */          Reduce using multiplication the factorial of the tallies
  %            Divide the factorial of the size by that product and return
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.