Probabilité de paire de cartes

9

Étant donné un jeu composé de N copies de cartes avec des valeurs entières [ 1 , M ] pour un total de N * M cartes, calculez la probabilité qu'une carte avec la valeur de 1 soit adjacente à une carte avec la valeur de 2 .

Votre solution peut être exacte ou approximative, et il n'est pas nécessaire qu'elle soit la même pour chaque exécution avec les mêmes entrées. La réponse donnée doit se situer à +/- 5% de la vraie solution (à moins de très rares chances que le RNG ne soit pas en votre faveur). Votre programme devrait donner la réponse dans un délai raisonnable (disons, moins de 10 minutes sur le matériel que vous possédez). Vous pouvez supposer que M et N sont raisonnablement petits et qu'une vérification des erreurs n'est pas requise.

Le jeu n'est pas cyclique, donc si la première carte est un 1 et la dernière carte est un 2 , cela ne répond pas aux exigences d'adjacence.

À titre de test, pour N = 4 et M = 13 (un jeu standard de 52 cartes), la solution attendue est de ~ 48,6%.

Voici un exemple d'implémentation sans golf en Python + NumPy utilisant des shuffles aléatoires:

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 sortie peut être sous n'importe quelle forme que vous trouvez commode (valeur de retour de fonction, sortie de terminal, fichier, etc.), et l'entrée peut être sous n'importe quelle forme que vous trouvez commode (paramètre de fonction, entrée de terminal, arg de ligne de commande, etc.)

Des trous de boucle standard s'appliquent.

C'est le code golf, le code le plus court (en octets) l'emporte.

Classement

helloworld922
la source
1
la contiguïté ne s'enroule pas est une torsion trompeusement compliquée
Sparr
@Sparr Vous m'avez donné une idée! :-)
Luis Mendo

Réponses:

2

Pyth, 23 22 octets

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

Exécute 10000 itérations. Le nombre peut être modifié sans frais d'octet. L'entrée est séparée de la nouvelle ligne. Prend environ 9 secondes sur mon ordinateur.

Manifestation

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.
isaacg
la source
2

MATL , 44 46 octets

Cela utilise la version 3.1.0 du langage, qui est antérieure à ce défi.

Le calcul se fait avec une boucle qui dessine 1000 réalisations aléatoires. Cela prend quelques secondes pour fonctionner. Cela pourrait être fait plus rapidement de manière vectorisée. L'entrée est de la forme [N M].

Ancienne version : génère un jeu de cartes aléatoire et le vérifie deux fois: d'abord vers l'avant puis vers l'arrière.

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

Nouvelle version : génère un jeu de cartes aléatoire, puis en ajoute une version inversée avec un 0entre les deux. De cette façon, la vérification peut être effectuée une seule fois, dans le sens direct. Cela économise deux octets.

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

Exemple

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

Explication

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
Luis Mendo
la source
1

LabVIEW, 58 primitives LabVIEW

crée des tableaux de cartes puis les mélange. Recherchez 1s puis vérifiez les cartes adjacentes pour 2s.

Eumel
la source
1

Pyth, 16 octets

JE?>J1-1^-1c2JQZ

Manifestation.

Cela suit la

  • faire une supposition éclairée,
  • vérifiez qu'il est assez proche,
  • répéter

stratégie de programmation. La supposition éclairée gagnante dans ce cas est

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

ce qui indique à peu près qu'il y a des Nchances de tomber dans des seaux, et une fraction de seaux valides l'est 2 / M. Les seaux étant des emplacements situés à côté de 0s, et les chances sont 1s.

L'erreur ne semble jamais dépasser 3% (de manière surprenante) et semble converger vers 0% à mesure que les paramètres augmentent (comme je m'y attendais).

L'entrée est séparée de la nouvelle ligne.

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

Vous pouvez enregistrer un personnage si vous acceptez le fait clairement évident False == 0et faites-le à la JE&>J1-1^-1c2JQplace.

Veedrac
la source
Cela se trouve être mon premier accès à Pyth (et ma première réponse), donc la critique et l'aide sont particulièrement les bienvenues.
Veedrac
1

MATL , 44 38 octets

Cela utilise également MATL version 3.1.0 , qui est antérieure à ce défi.

Nouvelle version, merci à Luis Mendo pour avoir économisé 4 octets!

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

Ancienne version (44 octets):

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

Explication

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

Par exemple,

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

Remarque (21/5/16): à partir de la version 18.0.0 de MATL, X+a été supprimée, mais Y+peut être utilisée à sa place. Les modifications de la version 3.1.0 à MATL 18.0.0 signifient que cette réponse peut maintenant être écrite en seulement 31 octets, *xO1e4:"2:Gtb*Z@w\TT2&Y+1=ah]Ym.

David
la source
Je sais qu'il y a déjà une réponse MATL, mais je pense que les méthodes sont assez différentes, donc j'ai encore posté celle-ci.
David
J'adore la convolution!
Luis Mendo
Vous pouvez enregistrer un peu de changement [1 1]en TTo. De plus, vous n'avez pas besoin de la virgule
Luis Mendo
@LuisMendo merci! Je pensais qu'il devait y avoir une meilleure façon de le faire!
David
Maintenant, je vois comment fonctionne la convolution ici. Utiliser un nommage des cartes basé sur 0 était très intelligent!
Luis Mendo
0

Mathematica, 93 92 91 octets

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

Toujours à la recherche d'un formulaire fermé ...

LegionMammal978
la source
cela va impliquer une boucle imbriquée de calculs de permutation.
Sparr