具有不可区分项目的排列


12

给定一个整数列表,输出整数的排列数量,其中不可区分的排列计数一次。如果有n整数,并且每组不可区分的数字都有length 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

当您说没有内置函数时,这包括我使用内置函数生成所有排列时所做的事情吗?
Maltysen '16

1
这看起来与计算多项式系数大致相同。对输入的相同条目进行计数是否会使它完全不同而不是被骗?
xnor

@xnor在这里,您实际上必须计算重复项,所以我想这不是那么简单。另一个是直接插入值。
qwr

@Maltysen可悲的是,我将不得不更新问题
qwr

1
@LuisMendo是的,尽管它不会像我想象的
那样有所作为

Answers:


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 '16

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 '16

@ 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

Ruby,75 74字节

Kinda希望Ruby的Math模块具有阶乘功能,因此我不必构建自己的模块。

->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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.