カードゲームの手のパターン


20

カードのデッキは、SスーツとRランクのデカルト積です。すべてではありませんが、多くのカードゲームがとを使用S=4していR∊{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

ウィキペディアのブリッジ手のパターンも参照してください。

編集:不要な制限を削除しました H≤R

編集:制約を追加 H≥1


Dがソートされていると仮定できますか?
orlp

1
@oripはい、それは私がD [i]が≥D[I + 1]によって意味したものだ
NGN

私が知っているカードは...ない0から1からスタート
RosLuP

@RosLuPどういう意味ですか?
ngn

私は何かを理解していなかったと確信しています...カードが番号1、2、...、13すべて* 4から表されている場合。例では「13 0 0 0」とはどういう意味ですか?0はカード0を意味しますか?
RosLuP

回答:


9

APL(Dyalog Unicode)、30文字

×/!⍨,z,1÷((z←!∘≢⊢)⌸⊢),×∘≢!⍨1⊥⊢

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

@orlpのformulaを使用します。


素晴らしい、よくやった!「+100」ボタンは、賞金を授与する前にさらに10時間待つ必要があることを示します。その後、さらに200を設定します。
ngn

勝った!ありがとう@jayprich
FrownyFrog

@FrownyFrog Jと比較してDyalog APLが好きですか?
ジョナ

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)各要素のd中のD時間、factorial(len(D))との積で除し、factorial(len(S))それぞれについてSのグループにD(例えば、[4, 4, 3, 2]グループを有する[[4, 4], [3], [2]])、最終的にで割りましたbinom(len(D) * R, sum(D))

または、数学表記では、mDのn個の一意の要素の多重度が含まれると仮定します。

|D|m1m2mn|D|RD1dDRd


2
少しの間、PPCGがLaTeXをサポートするようになったと思わせてくれました:)
ngn

私は136を得た2つの機能をインライン化しますが、多分それはもっとゴルフすることができます(i=0意味b()するR,Dための使用とのための使用n,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関数の外で)そして今朝投稿したコメントに対するngnの回答に応じてseqを使用する可能性があります
JayCe

6

ゼリー 22  20 バイト

-新しいクイックʋ、、および新しいモナドアトムを使用して-2バイト

ĠẈ!;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〜の要素の積
                 。!〜それぞれの階乗...
                   hM〜ヘッド。隣接する要素の数...
                     r8Q〜Dのランレングスエンコーディング。
c〜で割った...
                        .c〜間のnCr ...
                          *〜の製品
                           vz〜R、および...
                             lQ〜Dの長さ
                               s〜そしてDの合計
                                 〜暗黙的に出力します。

3

APL(Dyalog)、42バイト

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

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

まだゴルフ。


チャレンジ:30バイト
-ngn

@ngn挑戦は受け入れ
ウリエル

申し訳ありませんが、実際には30 文字です。情報を提供するリスクがあるため、私の文字の1つがClassic文字セットに含まれていないため、最初はそのことに気付きませんでした。
-ngn

@ ngnAdámの文字セットを使用して30バイトにすることはできませんか?
プロビー

@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番目の引数はスイートごとのデッキ内のカードの数です。


2

J、57バイト

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

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

これはO(golf)で実行され、多くのテストケースで窒息します(理論的には動作しますが)。しかし、私は特にそれらが繰り返されることを避けることで、それをトリミングすることに固執してい"1ます。誰かが助けたいと思うなら、ここに解析されたバージョンがあります...

メインフォークの右側は、デッキのすべての可能な取引であり、メインフォークの左側は、元の右側の引数、つまり、一致するスーツマスクです。

内部では、各「シャッフル」デッキから、最初の手の要素を取得し、キー/.を使用してそれらをグループ化し、結果を並べ替え、それが問題のスーツマスクと一致するかどうかを確認します。一致する合計数を合計し、可能なすべてのデッキの長さに分割します。

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

1
Orlpの公式はAPLで42点を獲得しましたが、Jで58点未満を獲得するでしょうか?
ウリエル

1
私はこれまでのところ45を取得していますf=:(([:!#)%[:*/[:!#/.~)@]**/@(]![)%+/@]![*#@] TIO
jayprich
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.