Permutasi dengan Item Tidak Dapat Dibedakan

12

Diberikan daftar bilangan bulat, hasilkan jumlah permutasi dari bilangan bulat, dengan permutasi yang tidak dapat dibedakan dihitung satu kali. Jika ada nbilangan bulat, dan setiap kelompok angka yang tidak dapat dibedakan memiliki panjang n_i, inin! / (n_1! * n_2! * ...)

Aturan

  • Input akan berupa daftar sebagai argumen untuk suatu fungsi atau program dengan 1 hingga 12 bilangan bulat non-negatif.

  • Output akan mencetak atau mengembalikan jumlah permutasi seperti dijelaskan di atas.

  • Tidak ada celah standar atau fungsi bawaan (menghasilkan permutasi, kombinasi, dll.). Faktorial diizinkan.

Uji Kasus

Input:

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

Output:

60
1
83160
qwr
sumber
ketika Anda mengatakan tidak ada builtin, apakah ini termasuk apa yang saya lakukan ketika saya menggunakan builtin untuk menghasilkan semua permutasi?
Maltysen
1
Ini sebagian besar terlihat sama dengan Hitung koefisien multinomial . Apakah menghitung entri yang identik untuk input membuatnya cukup berbeda untuk tidak menjadi korban penipuan?
xnor
@xnor baik di sini Anda benar-benar harus menghitung duplikat, sehingga tidak seperti yang mudah saya kira. Yang lainnya adalah cukup banyak memasukkan nilai.
qwr
@Maltysen sayangnya ya, saya harus memperbarui pertanyaan
qwr
1
@LuisMendo Ya itu, meskipun seharusnya tidak membuat perbedaan sejauh yang saya bisa bayangkan
qwr

Jawaban:

6

Python, 48 byte

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

Implementasi rekursif.

Dalam rumus,, n! / (n_1! * n_2! * ...)jika kita menghapus elemen pertama (katakanlah itu 1), jumlah permutasi untuk n-1elemen yang tersisa adalah

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

Jadi, kita mendapatkan jawabannya dengan mengalikan dengan n/n1, fraksi timbal balik dari elemen yang sama dengan yang pertama, dengan hasil rekursif untuk sisa daftar. Daftar kosong memberikan dasar kasus 1.

Tidak
sumber
Mengapa Anda tidak menaruh /l.count(l[0])pada akhirnya? Maka Anda tidak perlu floating point yang menjijikkan itu.
feersum
4

MATL , 14 13 12 byte

fpGu"@G=s:p/

Cobalah online!

Penjelasan

Pendekatannya sangat mirip dengan jawaban @ 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
Luis Mendo
sumber
3

05AB1E , 15 14 13 byte

Kode:

D©g!rÙv®yQO!/

Penjelasan:

               # 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

Menggunakan pengodean CP-1252 .

Cobalah online! .

Adnan
sumber
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

Menggunakan rumus yang diberikan, kecuali menghitung masing-masing faktorial secara bertahap (jadi misalnya yang r=r*++idikalibrasi secara efektifn! ).

Sunting: Awalnya saya menerima angka terbatas tetapi saya menyimpan 3 byte ketika @ user81655 menunjukkan bahwa saya hanya perlu mendukung bilangan bulat positif (walaupun saya benar-benar menerima bilangan bulat non-negatif).

Neil
sumber
r*=++i/(x-y?(y=x,c=1):++c),y=r=-1)|-r?
user81655
@ user81655 Ah, saya belum cukup membaca pertanyaan dan mengabaikan bahwa saya bisa mengandalkan nilai menjadi bilangan bulat positif. Saya tidak suka *=meskipun karena memperkenalkan kesalahan pembulatan.
Neil
2

Pyth, 11 byte

/.!lQ*F/V._

Suite uji

Menggunakan formula standar, n! / (count1! * count2! * ...) ,, kecuali bahwa faktorial dari penghitungan ditemukan dengan menghitung berapa kali setiap elemen terjadi dalam awalan yang mengarah ke itu, kemudian mengalikan semua angka-angka tersebut bersama-sama.

Penjelasan:

/.!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.
isaacg
sumber
1

Pyth - 14 12 byte

/F.!M+lQ/LQ{

Test Suite .

Maltysen
sumber
1

Ruby, 75 74 byte

Agak berharap Mathmodul Ruby memiliki fungsi faktorial sehingga saya tidak harus membangun sendiri.

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

CJam, 17 byte

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

Uji di sini.

Penjelasan

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.
Martin Ender
sumber
1

Jelly, 8 byte

W;ĠL€!:/

Cobalah 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
Biarawati Bocor
sumber
1

J, 13 byte

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

Pemakaian

   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

Penjelasan

#(%*/)&:!#/.~  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
mil
sumber