区別できないアイテムの順列


12

整数のリストを指定すると、整数の順列の数を出力し、区別できない順列を1回カウントします。ある場合はn整数であり、区別がつかない数字の各グループは、長さを持っているn_i、これはありますn! / (n_1! * n_2! * ...)

ルール

  • 入力は、1から12個の非負整数を持つ関数またはプログラムの引数としての何らかの形式のリストになります。

  • 出力は、上記のように順列の数を印刷または返します。

  • 標準的な抜け穴や組み込み関数(順列、組み合わせなどの生成)はありません。階乗が許可されます。

テストケース

入力:

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

出力:

60
1
83160

ビルトインがないと言うとき、これはすべての順列を生成するためにビルトインを使用したときに私がしたことを含みますか?
マルティセン

1
これは、「多項係数の計算」とほぼ同じに見えます。入力に対して同一のエントリをカウントすると、重複しないように十分に異なるようになりますか?
-xnor

@xnorはここでは実際に重複をカウントする必要があるため、それほど単純ではない思います。もう1つは、値のプラグインです。
-qwr

@Maltysen残念ながらはい、質問を更新する必要があります
-qwr

1
@LuisMendoはい、そうですが、想像できる限り違いはないはずです
-qwr

回答:


6

Python、48バイト

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

再帰的な実装。

数式でn! / (n_1! * n_2! * ...)、最初の要素を削除すると(たとえば1)、残りのn-1要素の順列の数は

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

したがって、n/n1最初の要素に等しい要素の逆数に、リストの残りの部分に再帰的な結果を掛けて、答えを得ることができます。空のリストは、基本ケース1を示します。


/l.count(l[0])最後に入れてみませんか?その後、その厄介な浮動小数点は必要ありません。
-feersum

4

MATL14 13 12バイト

fpGu"@G=s:p/

オンラインでお試しください!

説明

このアプローチは、@ 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

05AB1E15 14 13バイト

コード:

D©g!rÙv®yQO!/

説明:

               # 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

CP-1252エンコードを使用します。

オンラインでお試しください!


2

JavaScript(ES6)、64 61バイト

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

与えられた式を使用します。ただし、各階乗をインクリメンタルに計算します(たとえば、r=r*++i効果的に計算しますn!)。

編集:もともと有限の数値を受け入れましたが、正の整数のみをサポートする必要があることを@ user81655が指摘したときに3バイトを節約しました(実際に負ではない整数を受け入れます)。


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

@ user81655ああ、私は質問を十分に読んでおらず、値が正の整数であることに依存できることを見落としていました。*=丸め誤差が発生するため、私は好きではありません。
ニール

2

Pyth、11バイト

/.!lQ*F/V._

テストスイート

標準の数式を使用しますn! / (count1! * count2! * ...)。ただし、カウントの階乗は、それまでのプレフィックスで各要素が何回出現するかをカウントし、そのような数値をすべて乗算することで求められます。

説明:

/.!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

ルビー、75 74バイト

Mathちょっと、Rubyのモジュールに階乗関数があればいいのに、自分でビルドする必要はありませんでした。

->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バイト

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

ここでテストしてください。

説明

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

ゼリー、8バイト

W;ĠL€!:/

オンラインでお試しください!

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バイト

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

使用法

   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

説明

#(%*/)&:!#/.~  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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.