Handmuster in einem Kartenspiel


20

Ein Kartenspiel ist das kartesische Produkt von SFarben und RRängen. Viele, wenn auch nicht alle, Kartenspiele verwenden S=4und R∊{6,8,13}. Eine Hand von HKarten wird vom Deck ausgeteilt. Die Verteilung , auch als "Handmuster" bezeichnet, ist ein Array, das beschreibt, wie viele Karten Sie von jeder Farbe erhalten haben. Bei einer Verteilung Derfüllen len(D)=S, 1≤sum(D)=H≤S×R, 0≤D[i]≤R, D[i]≥D[i+1], findet die Wahrscheinlichkeit davon auftritt.

Eingabe: eine Ganzzahl Rund ein Array D.

Ausgabe: die Wahrscheinlichkeit mit mindestens 5 Nachkommastellen; nachfolgende Nullen können übersprungen werden; wissenschaftliche notation ist ok

Lücken verboten. Kürzeste Siege.

Tests:

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

Siehe auch Bridge-Handmuster in Wikipedia .

BEARBEITEN: unnötige Einschränkung fallen gelassen H≤R

EDIT: Einschränkung hinzugefügt H≥1


Können wir annehmen, dass D sortiert ist?
Orlp

1
@orip Ja, das habe ich mit D [i] ≥ D [i + 1]
ngn 20.11.17

Karten, die ich kenne, beginnen bei 1, nicht bei 0 ...
RosLuP

@RosLuP was meinst du?
22.

Ich bin mir sicher, dass ich etwas nicht verstanden habe ... Wenn Karten von Nummer 1,2, ..., 13 alle * 4 dargestellt werden; Also, was bedeutet es im Beispiel "13 0 0 0"? 0 bedeutet Karte 0?
RosLuP

Antworten:



8

Python 3, 134 Bytes

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)

Formel ist das Produkt binom(R, d)für jedes Element din DZeiten factorial(len(D)), geteilt durch das Produkt des factorial(len(S))für jede Sin den Gruppierungen von D(zB [4, 4, 3, 2]hat Gruppierungen [[4, 4], [3], [2]]) schließlich dividiert durch binom(len(D) * R, sum(D)).

Oder in mathematischer Notation, wenn m die Multiplizitäten der n eindeutigen Elemente in D enthält :

|D|!m1!m2!mn!(|D|RD)1dD(Rd)


2
für einen kurzen Moment hast du mich glauben lassen, dass PPCG jetzt LaTeX unterstützt :)
ngn 20.11.17

Inlining die beiden Funktionen bekam ich 136, aber vielleicht kann das mehr golfen werden (verwendet, um i=0zu bedeuten b()und verwendet R,Dfür n,k).
Jonathan Allan

7

R , 90 85 83 Bytes

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))

Probieren Sie es online!

Ich habe das Gleiche wie orlp beobachtet , aber ich habe eine nette Sprache ausgewählt, die kombinatorisch aufgebaut ist.

Erläuterung:

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)


Sie können mit folgendem Befehl weitere Daten speichern: "<"=choose(außerhalb der Funktion) und möglicherweise " seq" verwenden, abhängig von der Antwort von ngn auf den Kommentar, den ich heute Morgen gepostet habe.
JayCe

6

Jelly ,  22 bis  20 Bytes

-2 Bytes unter Verwendung eines neuen schnellen ʋund eines neuen monadischen Atoms

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

Ein dyadischer Link, der die ausgeteilt Verteilung D links und die Anzahl der Ränge R rechts annimmt und die Wahrscheinlichkeit des Auftretens zurückgibt.

Probieren Sie es online!oder sehen Sie die Testsuite an

Wie?

ĠẈ!;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 Bytes

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

Probieren Sie es online!

Erläuterung

 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 Bytes

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

Probieren Sie es hier aus! oder Überprüfen Sie alle Testfälle!

Wie funktioniert das

cc *.! lQ * F.cLvzQ * F.! hMr8Q.c * vzlQs ~ Volles Programm. D = Liste, R = Nummer.

   .! ~ Die Fakultät von ...
     lQ ~ Die Länge von D.
  * ~ Multipliziert mit ...
       * F ~ Das Produkt der Elemente von ...
         .c ~ Der nCr zwischen ...
           LQ ~ Jedes Element von D und ...
            vz ~ R.
 c ~ geteilt durch ...
               * F ~ Das Produkt der Elemente von ...
                 .! ~ Die Fakultät jedes ...
                   hM ~ Köpfe. Anzahl benachbarter Elemente in ...
                     r8Q ~ Die Lauflängencodierung von D.
c ~ geteilt durch ...
                        .c ~ Der nCr zwischen ...
                          * ~ Das Produkt von ...
                           vz ~ R und ...
                             lQ ~ Die Länge von D.
                               s ~ Und die Summe von D.
                                 ~ Implizit ausgeben.

3

APL (Dyalog) , 42 Bytes

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

Probieren Sie es online!

Immer noch Golf spielen.


Herausforderung: 30 Bytes
ngn

@ngn Herausforderung angenommen
Uriel

Tut mir leid, es sind tatsächlich 30 Zeichen . Mit dem Risiko, Informationen preiszugeben: Einer meiner Zeichensätze ist nicht im Classic-Zeichensatz enthalten, das habe ich zunächst nicht gemerkt.
ngn

@ngn Kannst du nicht einfach Adáms Zeichensatz verwenden , um 30 Bytes zu erhalten?
Probie

@Probie yep, das habe ich mit "SBCS" in der Kopfgeldbeschreibung gemeint
ngn

2

Clojure, 153 Bytes

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

Nur eine Brute-Force-Simulation, um mehr Präzision zu erzielen, erhöhen Sie die Iterationszahl und den "1 / N" -Wert am Ende entsprechend. Das erste Argument ist die Anzahl und das zweite Argument ist die Anzahl der Karten im Stapel pro Suite.


2

J, 57 Bytes

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

Probieren Sie es online!

Dies läuft in O (Golf) und wird an vielen Testfällen ersticken (obwohl theoretisch funktioniert), was in Ordnung wäre, wenn es golfer wäre. Aber ich bin fest entschlossen, es zu reduzieren, vor allem, wenn ich solche Wiederholungen vermeide "1. Wenn jemand helfen möchte, ist hier die analysierte Version ...

Die rechte Seite der Hauptgabel zeigt alle möglichen Deals des Decks , und die linke Seite der Hauptgabel zeigt nur das ursprüngliche rechte Argument, dh die Anzugmaske, mit der wir übereinstimmen.

Innerhalb jedes "gemischten" Decks nehmen wir die Elemente aus erster Hand , gruppieren sie dann mit der Taste /.und sortieren das Ergebnis und prüfen, ob dies mit der fraglichen Anzugmaske übereinstimmt. Wir addieren die Gesamtzahl der Übereinstimmungen und dividieren sie in die Länge aller möglichen Decks.

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

1
Orlps Formel erzielte 42 für APL, vielleicht würde das weniger als 58 für J ergeben?
Uriel

1
Ich bekomme so weit 45 f=:(([:!#)%[:*/[:!#/.~)@]**/@(]![)%+/@]![*#@] TIO
jayprich
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.