Probabilidade do par de cartões


9

Dado um baralho composto por N cópias de cartas com valores inteiros [ 1 , M ] para um total de N * M cartas, calcule a probabilidade de uma carta com o valor de 1 ser adjacente a uma carta com o valor de 2 .

Sua solução pode ser exata ou aproximada e não precisa ser a mesma para cada execução, com as mesmas entradas. A resposta dada deve estar dentro de +/- 5% da solução verdadeira (exceto as chances muito raras de que o RNG não esteja a seu favor). Seu programa deve fornecer a resposta em um período de tempo razoável (digamos, menos de 10 minutos em qualquer hardware que você tenha). Você pode assumir que M e N são razoavelmente pequenos e que a verificação de erros não é necessária.

O baralho não é cíclico; portanto, se a primeira carta for 1 e a última carta for 2 , isso não atenderá aos requisitos de adjacência.

Como um caso de teste, para N = 4 e M = 13 (um baralho de 52 cartas) a solução esperada é de ~ 48,6%.

Aqui está um exemplo de implementação não-golfada em Python + NumPy usando embaralhamento aleatório:

from __future__ import division
from numpy import *

def adjacent(N, M):
    deck = array([i for i in range(1, M+1)]*N)
    trials = 100000
    count = 0
    for i in range(trials):
        random.shuffle(deck)
        ores = (deck == 1)
        tres = (deck == 2)
        if(any(logical_and(ores[1:], tres[:-1])) or
           any(logical_and(ores[:-1], tres[1:]))):
            count += 1
    return count/trials

A saída pode estar em qualquer forma que você achar conveniente (valor de retorno da função, saída do terminal, arquivo etc.) e a entrada pode estar em qualquer forma que você achar conveniente (parâmetro de função, entrada do terminal, linha de comando arg, etc.)

Aplicam-se orifícios padrão.

Este é o código golf, o código mais curto (em bytes) vence.

Entre os melhores


11
adjacência não envolvendo em torno é uma torção enganosamente complicado
Sparr

@Sparr Você me deu uma ideia! :-)
Luis Mendo

Respostas:


2

Pitão, 23 22 bytes

csm}1sM.:.S*vzUQ2J^T4J

Executa 10000 iterações. O número pode ser alterado sem custo de bytes. A entrada é separada por nova linha. Demora cerca de 9 segundos no meu computador.

Demonstração

csm}1sM.:.S*vzUQ2J^T4J
                 J^T4     J = 10000
  m              J        Do the following J times.
           *vzUQ          Set up the deck. (0 .. n-1, repeated m times.)
         .S               Shuffle the deck.
       .:       2         Find all 2 elment substrings.
     sM                   Add them up.
   }1                     Check if any pairs add to 1 ([0, 1] or [1, 0])
 s                        Add up the results (True = 1, False = 0)
c                     J   Divide by J.

2

MATL , 44 46 bytes

Isso usa a versão 3.1.0 do idioma, que é anterior a esse desafio.

O cálculo é feito com um loop que desenha 1000 realizações aleatórias. Demora alguns segundos para executar. Isso poderia ser feito mais rapidamente de maneira vetorizada. Entrada é da forma [N M].

Versão antiga : gera um baralho aleatório e verifica duas vezes: primeiro na frente e depois na direção inversa.

itpw1)1e3:"2$twZ@w/Y]t1HhXfnwH1hXfn|bb]xxN$hYm

Nova versão : gera um baralho aleatório e anexa uma versão invertida com um 0meio. Dessa forma, a verificação pode ser feita apenas uma vez, na direção direta. Isso economiza dois bytes.

itpw1)1e3:"2$twZ@w/Y]tP0whh1HhXfngbb]xxN$hYm

Exemplo

>> matl itpw1)1e3:"2$twZ@w/Y]tP0whh1HhXfngbb]xxN$hYm
> [4 13]
0.469

Explicação

i                 % input: [N M]
tpw1)             % produce N*M and N
1e3:"             % repeat 1000 times
  2$twZ@w/Y]      % produce random deck of cards from 1 to N*M
  tP0whh          % append 0 and then flipped version of deck
  1Hh             % vector [1 2]
  Xf              % find one string/vector within another                          
  ng              % was it found at least once?
  bb              % bubble up element in stack, twice                     
]                 % end                                                     
xx                % delete top of the stack, twice
N$h               % vector with all elements in stack
Ym                % mean value


1

Pitão, 16 bytes

JE?>J1-1^-1c2JQZ

Demonstração.

Isto segue o

  • faça um palpite,
  • verifique se está perto o suficiente,
  • repetir

estratégia de programação. O palpite educado vencedor neste caso é

1 - (1 - 2 / M) ** N

o que diz aproximadamente que há Nchances de cair em baldes, e fração de baldes válidos é 2 / M. Os baldes sendo slots estão próximos a 0s e as chances são 1s.

O erro nunca parece ultrapassar 3% (surpreendentemente) e parece convergir para 0% à medida que os parâmetros aumentam (como eu esperaria).

A entrada é separada por nova linha.

              Q  Q = eval(input())
JE               J = eval(input())
  ?>J1           if J > 1
      -1^-1c2JQ  then 1 - (1 - 2 / J) ** Q
               Z else 0

Você pode salvar um personagem se aceitar o fato óbvio disso False == 0e o fizer JE&>J1-1^-1c2JQ.


Por acaso, é a minha primeira vez em Pyth (e minha primeira resposta); portanto, críticas e ajuda são especialmente bem-vindas.
Veedrac

1

MATL , 44 38 bytes

Isso também usa o MATL versão 3.1.0 , que é anterior a esse desafio.

Nova versão, obrigado a Luis Mendo por economizar 4 bytes!

iiXI*XJxO1e4XH:"JZ@I\TTo3X53$X+1=a+]H/

Versão antiga (44 bytes):

OiitXIx*XJx1e4XH:"JJZrI\[1 1]3X5,3$X+1=a+]H/

Explicação

i               % take input for N
i               % take input for M
XI              % save M into clipboard I
*XJ             % multiply N and M and store in clipboard J
x               % clear the stack
O               % make a zero to initialise count of pairs
1e4XH:"         % 1e4=10000, XH saves into clipboard H, : makes the vector 1:1e4
                % which is used to index a for loop, started using "
    JZ@         % Use randperm to generate a random permutation of the vector 1:N*M
    I\          % take the result mod M, now each card has a value one less than before
    TTo3X53$X+  % convolve vector of card values with [1 1] to do pairwise summation
    1=a         % find if any sums equal 1, which means there is a [0 1] or [1 0]         
    +           % add the logical value to the count of pairs
]
H/              % divide the count by the number of deals to get the probability

Por exemplo,

>> matl 'iiXI*XJxO1e4XH:"JZ@I\TTo3X53$X+1=a+]H/'
> 4
> 13
0.4861

Nota (21/5/16): A partir do MATL release 18.0.0, X+foi removida, mas Y+pode ser usada em seu lugar. As alterações da versão 3.1.0 para 18.0.0 do MATL significam que agora essa resposta pode ser escrita em apenas 31 bytes *xO1e4:"2:Gtb*Z@w\TT2&Y+1=ah]Ym,.


Eu sei que já existe uma resposta MATL, mas acho que os métodos são bem diferentes, então eu ainda postei essa.
David

Adoro convolução!
Luis Mendo

Você pode economizar um pouco de mudança [1 1]em TTo. Além disso, você não precisa de vírgula.
Luis Mendo

@LuisMendo thanks! Eu pensei que deveria ter havido uma maneira melhor de fazer isso!
David

Agora vejo como a convolução funciona aqui. O uso de nomes com base em 0 dos cartões foi muito inteligente!
Luis Mendo

0

Mathematica, 93 92 91 bytes

N@Count[RandomSample@Flatten[Range@#~Table~{#2}]~Table~{a=1*^5},{b=___,1,2,b}|{b,2,1,b}]/a&

Ainda à procura de um formulário fechado ...


isso envolverá um loop aninhado de cálculos de permutação.
Sparr
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.