纸牌游戏中的手形


20

一副纸牌是S西服和R等级的直角乘积。许多(尽管不是全部)纸牌游戏使用S=4R∊{6,8,13}。一副H牌从甲板上发出。它的分布(也称为“手形”)是一个数组,用于描述您从每套西服中获得多少张牌,而忽略西服的顺序(因此,就像是多套)。鉴于分布D满足len(D)=S1≤sum(D)=H≤S×R0≤D[i]≤RD[i]≥D[i+1],发现它发生的概率。

输入:一个整数R和一个数组D

输出:小数点后至少5位数字的概率;尾随零可以被跳过;科学记数法还可以。

禁止漏洞。最短的胜利。

测试:

R    D               probability
13   4 4 3 2     ->  0.2155117564516334148528314355068773
13   5 3 3 2     ->  0.1551684646451760586940386335649517
13   9 3 1 0     ->  0.0001004716813294328274372174524508
13   13 0 0 0    ->  0.0000000000062990780897964308603403
8    3 2 2 1     ->  0.4007096203759162602321667950144035
8    4 2 1 1     ->  0.1431105787056843786543452839337155
8    2 2 1 0     ->  0.3737486095661846496106785317018910
8    3 1 1 0     ->  0.2135706340378197997775305895439377
15   4 4 3 2 1   ->  0.1428926269185580521441708109954798
10   3 0 0       ->  0.0886699507389162561576354679802956
10   2 1 0       ->  0.6650246305418719211822660098522167
10   1 1 1       ->  0.2463054187192118226600985221674877

另请参阅Wikipedia中的桥手模式

编辑:删除不必要的限制 H≤R

编辑:添加约束 H≥1


我们可以假设D是排序的吗?
orlp

1
@orip是的,这就是我的意思由d [I]≥D[I + 1]
NGN

我知道的卡从1开始而不是从0开始...
RosLuP

@RosLuP是什么意思?
ngn

我确定我听不懂...如果卡片是从数字1,2,...,13代表* 4; 那么示例中的“ 13 0 0 0”是什么意思?0表示卡0?
RosLuP

Answers:



8

Python 3,134个字节

b=lambda n,k:k<1or n*b(n-1,k-1)/k
f=lambda R,D,i=1,s=1,t=0:D and b(R,D[0])*i/s*f(R,D[1:],i+1,(D[0]in D[1:])*s+1,t+D[0])or 1/b(~-i*R,t)

式是产品binom(R, d)的每个元素dD,时间factorial(len(D)),通过的产品划分factorial(len(S))为每个S在的分组D(例如[4, 4, 3, 2]具有的分组[[4, 4], [3], [2]]),最后除以binom(len(D) * R, sum(D))

或以数学符号表示,假设m包含D中n个唯一元素的多重性:

|d|1个2ñ|d|[Rd-1个dd[Rd


2
一个短暂的时刻,你让我相信PPCG现在支持LaTeX的:)
NGN

内联这两个功能我得到了136,但也许可以golfed以上(用途i=0的意思b()和用途R,Dn,k)。
乔纳森·艾伦,

7

R90 85 83字节

function(R,D,l=sum(D|1),K=choose)prod(K(R,D),1:l,1/gamma(1+table(D)))/K(R*l,sum(D))

在线尝试!

我观察到的东西与orlp相同,但是我选择了一种不错的语言,具有内置的combinatorics。

说明:

function(R,D,             # next are optional arguments
 l=sum(D|1),              # alias for length of D, aka S
 K=choose)                # alias for choose
  prod(                   # take the product of:
    K(R,D),               # "choose" is vectorized over R and D
    1:l,                  # S!
    1/gamma(1+            # gamma(n+1) = n! for integer n
     table(D))            # multiplicities of unique elements of D
  ) /                     # divide by
  K(R*l, sum(D))          # R*S choose H
                          # return last computation (which is all the computation)


您可以使用以下命令节省更多:("<"=choose功能之外),并可能使用seq,具体取决于ngn对我今天上午发布的评论的回答。
JayCe

6

果冻 22  20 字节

-2个字节,使用一个新的quick ʋ和一个单子原子

ĠẈ!;L×c⁸S¤ʋ
L!;c@֍P

双向链接,左侧为交易分布D,右侧为等级数R,返回出现的概率。

在线尝试!或见测试人员

怎么样?

ĠẈ!;L×c⁸S¤ʋ - Link 1, denomParts: list, distribution (D); number, ranks (R)
                                                                 e.g. [3,3,3,2,2]; 8
Ġ           - group indices of D by their values                      [[4,5],[1,2,3]]
 Ẉ          - length of each group                                    [2,3]
  !         - factorial (vectorises)                                  [2,6]
          ʋ - last four links as a dyad
            - ... i.e. totalWaysToDeal = f(list, distribution (D); number, ranks (R)):
    L       - length of D                                             5
     ×      - multiply by R = total number of cards                   40
         ¤  - nilad followed by link(s) as a nilad:
       ⁸    -   chain's left argument, D                              [3,3,3,2,2]
        S   -   sum = total cards dealt                               13
      c     - binomial                                        40C13 = 12033222880
   ;        - concatenate                                             [2,6,12033222880]                                                  

L!;c@֍P - Main link: list, distribution (D); number, ranks (R)
         -                                                  e.g. [3,3,3,2,2]; 8
L        - length of D = number of suits                         5
 !       - factorial                                             120
   c@    - R binomial (vectorised across) D     (8C3=56;8C2=28)  [56,56,56,28,28]
  ;      - concatenate                                           [120,56,56,56,28,28]
      ç  - call the last link (1) as a dyad = denomParts(D,R)    [2,6,12033222880]
     ÷   - divide (vectorises)                                   [120/2,56/6,56/12033222880,56,28,28]
       P - product                                               0.11441900924883391

5

05AB1E,21字节

cP¹g!*¹γ€g!P¹gI*¹Oc*/

在线尝试!

说明

 P                      # product of
c                       # bin(input1,input2)
     *                  # multiplied by
    !                   # fac of
  ¹g                    # length of input1
                    /   # divided by
           P            # product of
          !             # fac of each
        €g              # length of each
      ¹γ                # chunk of consecutive equal elements of input1
                   *    # multiplied by
                  c     # bin of
            ¹g          # length of input1
              I*        # times input2
                ¹O      # and sum of input1

3

Pyth,32个字节

cc*.!lQ*F.cLvzQ*F.!hMr8Q.c*vzlQs

在这里尝试!验证所有测试用例!

如何运作?

cc *。!lQ * F.cLvzQ * F。!hMr8Q.c * vzlQs〜完整程序。D =列表,R =数字。

   。!〜...的阶乘
     lQ〜D的长度
  *〜乘以...
       * F〜元素的乘积
         .c〜之间的nCr ...
           LQ〜D的每个元素,然后...
            vz〜R。
 c〜除以...
               * F〜元素的乘积
                 。!〜每个的阶乘...
                   嗯〜头。...中的相邻元素计数
                     r8Q〜D的游程长度编码。
c〜除以...
                        .c〜之间的nCr ...
                          *〜...的产品
                           vz〜R,然后...
                             lQ〜D的长度
                               s〜和D的总和。
                                 〜隐式输出。

3

APL(Dyalog),42字节

{×/(!≢⍵),(⍵!⍺),÷((+/⍵)!⍺×≢⍵),!≢¨⍵⊂⍨1,2≠/⍵}

在线尝试!

还在打高尔夫球。


挑战:30个字节
ngn

@ngn挑战已接受
Uriel

抱歉,实际上是30个字符。冒着泄露信息的风险:我的一个字符不在经典字符集中,一开始我并没有意识到。
ngn

@ngn不能仅使用Adám的字符集其设置为30个字节吗?
Probie

@Probie是的,这就是我在赏金描述中所说的“ SBCS”的意思
ngn

2

Clojure,153个字节

#(apply +(for[_(range 1e06):when(=(remove #{0}%)(reverse(sort(vals(frequencies(take(apply + %)(shuffle(for[i(range %2)j(range(count %))]j))))))))]1e-06))

只是蛮力模拟,为了获得更高的精度,相应地增加了迭代次数并最终增加了“ 1 / N”值。第一个参数是计数,第二个参数是每个套件的卡片组中的纸牌数。


2

J,57个字节

](#@]%~[:+/[-:"1[:\:~@(#/.~)"1+/@[{."1])i.@!@(*+/)A.(##\)

在线尝试!

这在O(golf)中运行,并且会阻塞许多测试用例(尽管从理论上讲是可行的),如果它是高尔夫球手,那会很好。但是我一直坚持将其缩小,尤其是避免重复这些"1。如果有人想帮忙,这里是经过解析的版本...

主叉的右侧是甲板上所有可能的交易,主叉的左侧只是原始的右侧arg,即我们要匹配的西服面罩。

在内部,从每个“混洗”的牌组中,我们取第一手元素,然后使用键/.对它们进行分组并对结果进行排序,然后检查是否与所讨论的西服面罩匹配。我们将确实匹配的总数相加,然后将其除以所有可能的套牌的长度。

┌─┬─────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────┐
│]│┌───────┬─────┬─────────────────────────────────────────────────────────────────────────────────┐│┌──────────────────────┬──┬─────────┐│
│ ││┌─┬─┬─┐│┌─┬─┐│┌──┬─────┬──────────────────────────────────────────────────────────────────────┐│││┌────────┬─┬─────────┐│A.│┌─┬─────┐││
│ │││#│@│]│││%│~│││[:│┌─┬─┐│┌─┬────────┬─────────────────────────────────────────────────────────┐│││││┌──┬─┬─┐│@│┌─┬─────┐││  ││#│┌─┬─┐│││
│ ││└─┴─┴─┘│└─┴─┘││  ││+│/│││[│┌──┬─┬─┐│┌──┬───────────────────────────┬────────────────────────┐│││││││i.│@│!││ ││*│┌─┬─┐│││  ││ ││#│\││││
│ ││       │     ││  │└─┴─┘││ ││-:│"│1│││[:│┌─────────────────────┬─┬─┐│┌───────────┬────────┬─┐│││││││└──┴─┴─┘│ ││ ││+│/││││  ││ │└─┴─┘│││
│ ││       │     ││  │     ││ │└──┴─┴─┘││  ││┌──────┬─┬──────────┐│"│1│││┌─────┬─┬─┐│┌──┬─┬─┐│]││││││││        │ ││ │└─┴─┘│││  │└─┴─────┘││
│ ││       │     ││  │     ││ │        ││  │││┌──┬─┐│@│┌──────┬─┐││ │ ││││┌─┬─┐│@│[│││{.│"│1││ ││││││││        │ │└─┴─────┘││  │         ││
│ ││       │     ││  │     ││ │        ││  ││││\:│~││ ││┌─┬──┐│~│││ │ │││││+│/││ │ ││└──┴─┴─┘│ │││││││└────────┴─┴─────────┘│  │         ││
│ ││       │     ││  │     ││ │        ││  │││└──┴─┘│ │││#│/.││ │││ │ ││││└─┴─┘│ │ ││        │ ││││││└──────────────────────┴──┴─────────┘│
│ ││       │     ││  │     ││ │        ││  │││      │ ││└─┴──┘│ │││ │ │││└─────┴─┴─┘│        │ ││││││                                     │
│ ││       │     ││  │     ││ │        ││  │││      │ │└──────┴─┘││ │ ││└───────────┴────────┴─┘│││││                                     │
│ ││       │     ││  │     ││ │        ││  ││└──────┴─┴──────────┘│ │ ││                        │││││                                     │
│ ││       │     ││  │     ││ │        ││  │└─────────────────────┴─┴─┘│                        │││││                                     │
│ ││       │     ││  │     ││ │        │└──┴───────────────────────────┴────────────────────────┘││││                                     │
│ ││       │     ││  │     │└─┴────────┴─────────────────────────────────────────────────────────┘│││                                     │
│ ││       │     │└──┴─────┴──────────────────────────────────────────────────────────────────────┘││                                     │
│ │└───────┴─────┴─────────────────────────────────────────────────────────────────────────────────┘│                                     │
└─┴─────────────────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────┘

1
Orlp的APL公式得分为42,也许对J得分不到58?
Uriel's

1
到目前为止,我的总f=:(([:!#)%[:*/[:!#/.~)@]**/@(]![)%+/@]![*#@]
成绩
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.