1

我正在尝试在 Google 表格中编写一个对“连接性”扑克牌进行分类的函数。

输入:我们得到一个“翻牌”列表(3 张随机牌)。这些以数值形式给出,其中 2=2, 3=3 ... 11 = Jack, 12 = Queen, 13 = King, 14 = ace

我希望能够使用三个不同的指标对这些翻牌进行分类:

1)连通性 - 立即可能的顺子数量:示例 1:FLOP [5 6 7] 具有三个连通性,因为 43/84/98 完成了顺子。示例 2:FLOP [KQJ] 有两个连通性,如 {AT, T9) 完成顺子

2)联动- 可能的顺子听牌数量:示例 1: FLOP [K 9 2] 有联动 3,因为 {QJ, QT, JT} 是可能的顺子听牌。示例 2:FLOP [JT 4] 有 9 连杆,因为 {AK, AQ, KQ, K9, Q9, Q8, 98, 97, 76} 是顺子听牌。

3)跨度- 可以完成可能的顺子抽签之一的不同等级的数量。示例 1:[K 9 2] 的跨度为 3,因为 {Q, J, T} 是可以完成可能顺子的行列。示例 2:[JT 4] 的跨度为 6,因为等级 {A, K, Q, 9, 8, 7} 是可以完成可能顺子听牌的等级。


我想不出用谷歌表格做到这一点的干净方法。起初我尝试了一些笨拙的 IFS 语句,但是有太多的边缘情况,这太快了。

我可以很容易地用普通语言做到这一点,但我不知道如何用工作表干净地做到这一点。

4

1 回答 1

1

1)连接性

我认为您是对的,它不太适合 Google 表格。不过,我的想法是使用这样的矩阵来设置一个滑动窗口来查看 13 种可能的牌中的 5 组(2-6、3-7、4-8 等):

在此处输入图像描述

然后,如果只有两个空白等待填补以弥补 5 的运行(即在这 5 运行的某处抽牌匹配的所有三张牌),则必须构成一个连接项。

公式最终看起来像这样:

=ArrayFormula(countif(mmult(if((column(A1:M9)>=row(A1:M9))*(column(A1:M9)<row(A1:M9)+5),1,0),
if(isnumber(match(sequence(13),match(A1:A3,B:B,0),0)),1,0)),3))

其中 A 列包含抽出的三张牌,B 列包含它们可能的数字或字母 2、3、4、5、6、7、8、9、T、J、Q、K 和 A 的列表。

在此处输入图像描述

编辑

我认为滑动窗口是正确的想法,但是如果不使用实际的矩阵,可以写得更简洁:

=ArrayFormula(countif(countifs(match(A1:A3,B:B,0),">="&sequence(9,1,1),match(A1:A3,B:B,0),"<="&sequence(9,1,5)),3))

2)联动

从表面上看,您可以使用相同的滑动窗口的想法,但这次计算 5 范围内有多少张牌只有 2 张牌中有 5 张牌(所以如果有另外两张牌,您就有顺子抽牌)。问题是这会产生重复计算。假设你有 [34X],其中 X 是我们不感兴趣的牌。2-6 范围内的顺子听牌是 {25,26,56}。然后,如果您移动到范围 3-7,顺子听牌是 {56,57,67}。所以 56 出现了两次。这样做的结果是您必须实际枚举所有不同的对,检查它们是否可以在每个范围内产生顺子抽牌,然后删除重复的代码,这是相当多的代码 - 但我认为可以做到。无论如何,您需要枚举它们来执行 3)。

我产生这样的枚举:

=int(sequence(169,1,0)/13)

=mod(sequence(169,1,0),13)

所以为方便起见,卡片的编号从 0 到 12

并应用以下条件来抽牌:

  • 第一张卡小于第二张卡
  • 第一个大于等于窗口开始的卡片
  • 第二张卡片小于或等于窗口结束
  • 第一张牌不在翻牌圈
  • 第二张牌不在翻牌圈。

翻牌的条件是:

  • 第一张卡小于第二张卡
  • 第一张大于或等于窗口开始的卡片
  • 第二张卡片小于或等于窗口结束
  • 第一张牌在翻牌圈
  • 第二张牌在翻牌。

翻牌应该只有一对牌,这些牌与可能的对子组合在一起,在每个窗口中构成四张不同的牌。

将所有这些放在一起并使用标准 mmult 公式计算行和列总计,您将获得:

=ArrayFormula(countunique(if(mmult((int(sequence(169,1,0)/13)<mod(sequence(169,1,0),13))*( int(sequence(169,1,0)/13)>=sequence(1,9,0))* (mod(sequence(169,1,0),13)<=sequence(1,9,4))
*isna(match(int(sequence(169,1,0)/13)+1,match(A1:A3,B1:B13,0),0))*isna(match(mod(sequence(169,1,0),13)+1,match(A1:A3,B1:B13,0),0))
*(mmult(sequence(1,169,1,0),(int(sequence(169,1,0)/13)<mod(sequence(169,1,0),13))*( int(sequence(169,1,0)/13)>=sequence(1,9,0))* (mod(sequence(169,1,0),13)<=sequence(1,9,4))
*isnumber(match(int(sequence(169,1,0)/13)+1,match(A1:A3,B1:B13,0),0))*isnumber(match(mod(sequence(169,1,0),13)+1,match(A1:A3,B1:B13,0),0)))=1),sequence(9,1,1,0)),int(sequence(169,1,0)/13)&mod(sequence(169,1,0),13)))-1)

在此处输入图像描述

3)跨度

这很简单 - 只需将这些对放入单个列并计算唯一值:

=ArrayFormula(countunique(flatten(if(mmult((int(sequence(169,1,0)/13)<mod(sequence(169,1,0),13))*( int(sequence(169,1,0)/13)>=sequence(1,9,0))* (mod(sequence(169,1,0),13)<=sequence(1,9,4))
*isna(match(int(sequence(169,1,0)/13)+1,match(A1:A3,B1:B13,0),0))*isna(match(mod(sequence(169,1,0),13)+1,match(A1:A3,B1:B13,0),0))
*(mmult(sequence(1,169,1,0),(int(sequence(169,1,0)/13)<mod(sequence(169,1,0),13))*( int(sequence(169,1,0)/13)>=sequence(1,9,0))* (mod(sequence(169,1,0),13)<=sequence(1,9,4))
*isnumber(match(int(sequence(169,1,0)/13)+1,match(A1:A3,B1:B13,0),0))*isnumber(match(mod(sequence(169,1,0),13)+1,match(A1:A3,B1:B13,0),0)))=1),sequence(9,1,1,0)),{int(sequence(169,1,0)/13),mod(sequence(169,1,0),13)})))-1)

在此处输入图像描述

于 2020-05-10T21:40:17.243 回答