Mathematica 收集列表中的元素

Mathematica collecting elements in a list

鉴于生成的 256 个元组:

Tuples[{a,b,c,d},4] = {{a,a,a,a},{a,a,a,b}...,{d,d,d,d}}

我想过滤所有恰好有 3 个同类的元组。例如,我想保留 {c,b,c,c} & {a,a,d,a} 等。但不保留 {d,d,d,d} 或 {a,b,b,c} .

我知道有:

Binomial[4,3]*4*3 = 48

来自简单数学的此类元组。但我正在寻找一种计算这些的编程方式。

我的最终目标来自元组:

Tuples[{1,2,3,...,n},k]

我想知道这些元组中有多少恰好有一个子集具有 m 种,所有其他子组的大小都小于 m。

如果您有兴趣,这个问题源于以下问题:在游戏“Cards Against Humanity”中获胜之前平均玩了多少轮?假设我们有 n 个玩家,第一个有 x 张牌的人获胜。

这将找到您的 48 个元组

Select[Tuples[{a, b, c, d}, 4], 
  MatchQ[Sort[#], {a_, a_, a_, b_} | {b_, a_, a_, a_}] && 
  Length[Union[#]] != 1 &]

这将向您显示超过 1,...,6 的四个项目的元组,其中 m 个相同项目和所有其他项目出现次数少于 m 次。

m = 2;
f[v_] := Module[{runlens},
  runlens = Sort[Map[Length, Split[Sort[v]]]]; 
  runlens[[-1]] == m && If[Length[runlens] == 1, True, runlens[[-2]] < m]]
];
Select[Tuples[Range[6], 4], f]

对该结果使用 Count,您就会知道自己有多少。

另一种方法:

Select[ Tuples[{a, b, c, d}, 4] ,
 ((Count[#, 3] == 1 && Max[#] == 3) &@Tally[#][[All, 2]] ) & ]

当然,如果集合大小大于列表长度的一半,则检查 MaxCount

是多余的