Probabilidad de par de cartas


9

Dado un mazo que consiste en N copias de cartas con valores enteros [ 1 , M ] para un total de N * M cartas, calcule la probabilidad de que una carta con el valor de 1 sea ​​adyacente a una carta con el valor de 2 .

Su solución puede ser exacta o aproximada, y no necesita ser la misma para cada ejecución con las mismas entradas. La respuesta dada debe estar dentro de +/- 5% de la solución verdadera (salvo posibilidades realmente raras de que el RNG no esté a su favor). Su programa debe dar la respuesta en un tiempo razonable (digamos, menos de 10 minutos en cualquier hardware que tenga). Puede suponer que M y N son razonablemente pequeños y no se requiere verificación de errores.

El mazo no es cíclico, por lo que si la primera carta es un 1 y la última es un 2 , esto no cumple con los requisitos de adyacencia.

Como caso de prueba, para N = 4 y M = 13 (una baraja estándar de 52 cartas) la solución esperada es ~ 48.6%.

Aquí hay un ejemplo de implementación sin golf en Python + NumPy usando aleatorios aleatorios:

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

La salida puede estar en cualquier forma que le resulte conveniente (valor de retorno de función, salida de terminal, archivo, etc.), y la entrada puede estar en cualquier forma que le parezca conveniente (parámetro de función, entrada de terminal, línea de comando arg, etc.)

Se aplican agujeros de bucle estándar.

Este es el código de golf, gana el código más corto (en bytes).

Tabla de clasificación


1
la adyacencia no es un giro engañosamente complicado
Sparr

@Sparr ¡Me diste una idea! :-)
Luis Mendo

Respuestas:


2

Pyth, 23 22 bytes

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

Ejecuta 10000 iteraciones. El número se puede cambiar sin costo de byte. La entrada está separada por una nueva línea. Toma alrededor de 9 segundos en mi computadora.

Demostración

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

Utiliza la versión 3.1.0 del lenguaje, que es anterior a este desafío.

El cálculo se realiza con un bucle que dibuja 1000 realizaciones aleatorias. Tarda un par de segundos en ejecutarse. Se podría hacer más rápido de forma vectorizada. La entrada es de la forma [N M].

Versión anterior : genera un mazo de cartas al azar y lo verifica dos veces: primero en adelante y luego en retroceso.

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

Nueva versión : genera un mazo de cartas al azar y luego agrega una versión invertida con un 0intermedio. De esa manera, la verificación se puede hacer solo una vez, en la dirección hacia adelante. Esto ahorra dos bytes.

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

Ejemplo

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

Explicación

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

Pyth, 16 bytes

JE?>J1-1^-1c2JQZ

Demostración.

Esto sigue el

  • hacer una conjetura educada,
  • comprueba que está lo suficientemente cerca,
  • repetir

estrategia de programación. La suposición educada ganadora en este caso es

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

lo que más o menos dice que hay Nposibilidades de caer en cubos, y la fracción de cubos válidos es 2 / M. Los cubos son ranuras ubicadas al lado de 0s, y las posibilidades son 1s.

El error nunca parece superar el 3% (sorprendentemente), y parece converger al 0% a medida que los parámetros se hacen más grandes (como era de esperar).

La entrada está separada por una nueva línea.

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

Puede guardar un personaje si acepta el hecho claramente obvio de eso False == 0, y lo hace en su JE&>J1-1^-1c2JQlugar.


Esta es mi primera visita a Pyth (y mi primera respuesta), por lo que las críticas y la ayuda son especialmente bienvenidas.
Veedrac

1

MATL , 44 38 bytes

Esto también usa MATL versión 3.1.0 , que es anterior a este desafío.

Nueva versión, gracias a Luis Mendo por guardar 4 bytes.

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

Versión anterior (44 bytes):

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

Explicación

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 ejemplo,

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

Nota (21/5/16): a partir de la versión 18.0.0 de MATL, X+se ha eliminado, pero Y+se puede utilizar en su lugar. Los cambios desde la versión 3.1.0 a MAT 18.0.0 media que esta respuesta se puede escribir en sólo 31 bytes, *xO1e4:"2:Gtb*Z@w\TT2&Y+1=ah]Ym.


Sé que ya hay una respuesta MATL, pero creo que los métodos son bastante diferentes, por lo que todavía he publicado esta.
David

¡Amo la convolución!
Luis Mendo

Puede ahorrar un poco cambiante [1 1]en TTo. Además, no necesitas la coma
Luis Mendo

@LuisMendo gracias! ¡Pensé que debía haber una mejor manera de hacerlo!
David

Ahora veo cómo funciona la convolución aquí. ¡Usar nombres de tarjetas basados ​​en 0 fue muy 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&

Todavía buscando una forma cerrada ...


implicará un ciclo anidado de cálculos de permutación.
Sparr
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.