Padrões de mão em um jogo de cartas

20

Um baralho de cartas é o produto cartesiano de Snaipes e Rposições. Muitos, embora não todos, jogos de cartas usam S=4e R∊{6,8,13}. Uma mão de Hcartas é distribuída do baralho. Sua distribuição , também conhecida como "padrão das mãos", é uma matriz que descreve quantas cartas você recebeu de cada naipe, ignorando a ordem dos naipes (portanto, é como um conjunto múltiplo). Dada uma distribuição Dsatisfatória len(D)=S, 1≤sum(D)=H≤S×R, 0≤D[i]≤R, D[i]≥D[i+1], encontrar a probabilidade da sua ocorrência.

Entrada: um número inteiro Re uma matriz D.

Saída: a probabilidade com pelo menos 5 dígitos após a marca decimal; zeros à direita podem ser ignorados; notação científica está ok.

Falhas proibidas. Vitórias mais curtas.

Testes:

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

Veja também Bridge hand patterns na Wikipedia .

EDIT: eliminou restrições desnecessárias H≤R

EDIT: restrição adicionada H≥1

ngn
fonte
Podemos assumir que D é classificado?
Orlp
1
@orip sim, isso é o que eu quis dizer com D [i] ≥D [i + 1]
NGN
Os cartões que eu conheço começam de 1, não de 0 ...
RosLuP 22/11
@RosLuP, o que você quer dizer?
NGN
Tenho certeza de que não entendi algo ... Se os cartões são representados a partir do número 1,2, ..., 13 todos * 4; então, o que significa "13 0 0 0" no exemplo? 0 significa cartão 0?
RosLuP

Respostas:

9

APL (Dyalog Unicode) , 30 caracteres

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

Experimente online!

Usando a fórmula do @ orlp .

FrownyFrog
fonte
Excelente, bem feito! O botão "+100" indica que devo esperar mais 10 horas antes de poder conceder a recompensa. Depois disso, montarei outro para +200.
NGN
Yay eu ganho! Obrigado @jayprich
FrownyFrog
@FrownyFrog Como você gosta do Dyalog APL em comparação com o J?
Jonah
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)

Formula é o produto de binom(R, d)cada elemento dem D, times factorial(len(D)), dividido pelo produto de factorial(len(S))cada elemento Snos agrupamentos de D(por exemplo, [4, 4, 3, 2]possui agrupamentos[[4, 4], [3], [2]] ), finalmente dividido por binom(len(D) * R, sum(D)).

Ou na notação matemática, supondo que m contenha as multiplicidades dos n elementos únicos em D :

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

orlp
fonte
2
por um momento breve você me fez acreditar PPCG agora suporta LaTeX :)
NGN
Incluindo as duas funções, obtive 136, mas talvez isso possa ser mais praticado (usos i=0para significar b()e usos R,Dpara 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))

Experimente online!

Observei a mesma coisa que o orlp , mas escolhi uma linguagem agradável que possui componentes combinatórios.

Explicação:

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)

Giuseppe
fonte
Você pode economizar um pouco mais com isso: "<"=choose(fora da função) e potencialmente usar seq, dependendo da resposta da ngn ao comentário que eu publiquei esta manhã.
Jayce
6

Geléia ,  22  20 bytes

-2 bytes usando um novo ʋátomo rápido ,, e um novo monádico

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

Um link diádico, com a distribuição distribuída, D, à esquerda, e o número de classificações, R, à direita, que retorna a probabilidade de ocorrência.

Experimente online! ou veja a suíte de testes

Quão?

ĠẈ!;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
Jonathan Allan
fonte
5

05AB1E , 21 bytes

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

Experimente online!

Explicação

 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
Emigna
fonte
3

Pitão , 32 bytes

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

Experimente aqui! ou Verifique todos os casos de teste!

Como isso funciona?

cc *.! lQ * F.cLvzQ * F.! hMr8Q.c * vzlQs ~ Programa completo. D = lista, R = número.

   .! ~ O fatorial de ...
     lQ ~ O comprimento de D.
  * ~ Multiplicado por ...
       * F ~ O produto dos elementos de ...
         .c ~ O nCr entre ...
           LQ ~ Cada elemento de D e ...
            vz ~ R.
 c ~ Dividido por ...
               * F ~ O produto dos elementos de ...
                 .! ~ O fatorial de cada ...
                   hM ~ Cabeças. Contagem de elementos adjacentes em ...
                     r8Q ~ A codificação do comprimento da execução de D.
c ~ Dividido por ...
                        .c ~ O nCr entre ...
                          * ~ O produto de ...
                           vz ~ R e ...
                             lQ ~ O comprimento de D.
                               s ~ E a soma de D.
                                 ~ Saída implicitamente.
Mr. Xcoder
fonte
3

APL (Dyalog) , 42 bytes

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

Experimente online!

Ainda jogando golfe.

Uriel
fonte
desafio: 30 bytes
ngn 23/11
desafio @ngn aceito
Uriel
Desculpe, na verdade são 30 caracteres . Com o risco de divulgar informações: um dos meus caracteres não está no charset Clássico, não percebi isso no começo.
NGN
@ngn Você não pode simplesmente usar o conjunto de caracteres de Adám para obter 30 bytes?
Probie
@Probie sim, isso é o que eu quis dizer com "SBCS" na descrição de recompensas
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))

Apenas uma simulação de força bruta, para obter mais precisão, aumente a contagem de iterações e o valor "1 / N" no final. O primeiro argumento é a contagem e o segundo argumento é o número de cartas no baralho por suíte.

NikoNyrh
fonte
2

J, 57 bytes

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

Experimente online!

Isso é executado em O (golfe) e afogará muitos dos casos de teste (embora funcione teoricamente), o que seria bom se fosse mais golfista. Mas eu estou preso em apará-lo, especialmente em evitar os repetidos "1. Se alguém quiser ajudar, aqui está a versão analisada ...

O lado direito do garfo principal é o possível negócio do baralho , e o lado esquerdo do garfo principal é apenas o argumento original à direita, ou seja, a máscara do naipe com a qual estamos combinando.

No interior, de cada baralho "embaralhado", pegamos os elementos de primeira mão , depois os agrupamos usando a tecla /.e classificamos o resultado e verificamos se isso corresponde à máscara do traje em questão. Adicionamos o número total correspondente e o dividimos pelo comprimento de todos os decks possíveis.

┌─┬─────────────────────────────────────────────────────────────────────────────────────────────────┬─────────────────────────────────────┐
│]│┌───────┬─────┬─────────────────────────────────────────────────────────────────────────────────┐│┌──────────────────────┬──┬─────────┐│
│ ││┌─┬─┬─┐│┌─┬─┐│┌──┬─────┬──────────────────────────────────────────────────────────────────────┐│││┌────────┬─┬─────────┐│A.│┌─┬─────┐││
│ │││#│@│]│││%│~│││[:│┌─┬─┐│┌─┬────────┬─────────────────────────────────────────────────────────┐│││││┌──┬─┬─┐│@│┌─┬─────┐││  ││#│┌─┬─┐│││
│ ││└─┴─┴─┘│└─┴─┘││  ││+│/│││[│┌──┬─┬─┐│┌──┬───────────────────────────┬────────────────────────┐│││││││i.│@│!││ ││*│┌─┬─┐│││  ││ ││#│\││││
│ ││       │     ││  │└─┴─┘││ ││-:│"│1│││[:│┌─────────────────────┬─┬─┐│┌───────────┬────────┬─┐│││││││└──┴─┴─┘│ ││ ││+│/││││  ││ │└─┴─┘│││
│ ││       │     ││  │     ││ │└──┴─┴─┘││  ││┌──────┬─┬──────────┐│"│1│││┌─────┬─┬─┐│┌──┬─┬─┐│]││││││││        │ ││ │└─┴─┘│││  │└─┴─────┘││
│ ││       │     ││  │     ││ │        ││  │││┌──┬─┐│@│┌──────┬─┐││ │ ││││┌─┬─┐│@│[│││{.│"│1││ ││││││││        │ │└─┴─────┘││  │         ││
│ ││       │     ││  │     ││ │        ││  ││││\:│~││ ││┌─┬──┐│~│││ │ │││││+│/││ │ ││└──┴─┴─┘│ │││││││└────────┴─┴─────────┘│  │         ││
│ ││       │     ││  │     ││ │        ││  │││└──┴─┘│ │││#│/.││ │││ │ ││││└─┴─┘│ │ ││        │ ││││││└──────────────────────┴──┴─────────┘│
│ ││       │     ││  │     ││ │        ││  │││      │ ││└─┴──┘│ │││ │ │││└─────┴─┴─┘│        │ ││││││                                     │
│ ││       │     ││  │     ││ │        ││  │││      │ │└──────┴─┘││ │ ││└───────────┴────────┴─┘│││││                                     │
│ ││       │     ││  │     ││ │        ││  ││└──────┴─┴──────────┘│ │ ││                        │││││                                     │
│ ││       │     ││  │     ││ │        ││  │└─────────────────────┴─┴─┘│                        │││││                                     │
│ ││       │     ││  │     ││ │        │└──┴───────────────────────────┴────────────────────────┘││││                                     │
│ ││       │     ││  │     │└─┴────────┴─────────────────────────────────────────────────────────┘│││                                     │
│ ││       │     │└──┴─────┴──────────────────────────────────────────────────────────────────────┘││                                     │
│ │└───────┴─────┴─────────────────────────────────────────────────────────────────────────────────┘│                                     │
└─┴─────────────────────────────────────────────────────────────────────────────────────────────────┴─────────────────────────────────────┘
Jonah
fonte
1
A fórmula de Orlp marcou 42 para APL, talvez com menos de 58 em J?
Uriel
1
Recebo 45 até agora dessa forma f=:(([:!#)%[:*/[:!#/.~)@]**/@(]![)%+/@]![*#@] TIO
jayprich