Probabilità della coppia di carte


9

Dato un mazzo composto da N copie di carte con valori interi [ 1 , M ] per un totale di N * M carte, calcola la probabilità che una carta con il valore di 1 sia adiacente a una carta del valore di 2 .

La tua soluzione potrebbe essere esatta o approssimata e non deve essere la stessa per ogni corsa dati gli stessi input. La risposta data dovrebbe essere entro il +/- 5% della soluzione reale (salvo le possibilità molto rare che l'RNG non sia a tuo favore). Il tuo programma dovrebbe dare la risposta in un ragionevole lasso di tempo (diciamo, meno di 10 minuti su qualunque hardware tu abbia). Si può presumere che M e N siano ragionevolmente piccoli e che non sia richiesto il controllo degli errori.

Il mazzo non è ciclico, quindi se la prima carta è un 1 e l'ultima carta è un 2 , questo non soddisfa i requisiti di adiacenza.

Come caso di prova, per N = 4 e M = 13 (un mazzo standard da 52 carte) la soluzione prevista è ~ 48,6%.

Ecco un esempio di implementazione senza golf in Python + NumPy usando shuffle casuale:

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

L'output può essere in qualsiasi forma che ritieni utile (valore di ritorno della funzione, output del terminale, file, ecc.) E l'input può essere in qualsiasi forma che ritieni conveniente (parametro della funzione, input del terminale, arg della riga di comando, ecc.)

Si applicano fori standard.

Questo è il codice golf, vince il codice più breve (in byte).

Classifica


1
l'adiacenza che non avvolge è una svolta ingannevolmente complicata
Sparr il

@Sparr Mi hai dato un'idea! :-)
Luis Mendo il

Risposte:


2

Pyth, 23 22 byte

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

Esegue 10000 iterazioni. Il numero può essere modificato senza costi byte. L'input è separato da una nuova riga. Richiede circa 9 secondi sul mio computer.

Dimostrazione

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 byte

Questo utilizza la versione 3.1.0 della lingua, che è precedente a questa sfida.

Il calcolo viene eseguito con un ciclo che disegna 1000 realizzazioni casuali. Ci vogliono un paio di secondi per correre. Potrebbe essere fatto più velocemente in modo vettoriale. L'input è nella forma [N M].

Vecchia versione : genera un mazzo di carte a caso e lo controlla due volte: prima in avanti e poi in direzione indietro.

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

Nuova versione : genera un mazzo di carte a caso e quindi ne aggiunge una versione capovolta con una via 0di mezzo. In questo modo il controllo può essere effettuato una sola volta, in avanti. Ciò consente di risparmiare due byte.

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

Esempio

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

Spiegazione

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 byte

JE?>J1-1^-1c2JQZ

Dimostrazione.

Questo segue il

  • fare un'ipotesi colta,
  • controlla che sia abbastanza vicino,
  • ripetere

strategia di programmazione. L'ipotesi vincente in questo caso è

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

che dice approssimativamente che ci sono Npossibilità di cadere in secchi, e la frazione di secchi validi è 2 / M. I secchi sono slot posti accanto a se 0le probabilità sono 1s.

L'errore non sembra mai superare il 3% (sorprendentemente) e sembra convergere allo 0% man mano che i parametri diventano più grandi (come mi aspetterei).

L'input è separato da una nuova riga.

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

Puoi salvare un personaggio se accetti il ​​fatto chiaramente ovvio False == 0e JE&>J1-1^-1c2JQinvece lo fai .


Questo sembra essere il mio primo tentativo su Pyth (e la mia prima risposta), quindi le critiche e l'aiuto sono particolarmente graditi.
Veedrac,

1

MATL , 44 38 byte

Questo utilizza anche MATL versione 3.1.0 , che è precedente a questa sfida.

Nuova versione, grazie a Luis Mendo per aver salvato 4 byte!

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

Vecchia versione (44 byte):

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

Spiegazione

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

Per esempio,

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

Nota (21/5/16): A partire dalla versione 18.0.0 di MATL, X+è stato rimosso, ma Y+può essere utilizzato al suo posto. I cambiamenti da MATL versione 3.1.0 a 18.0.0 significa che questa risposta può ora essere scritto in soli 31 byte, *xO1e4:"2:Gtb*Z@w\TT2&Y+1=ah]Ym.


So che esiste già una risposta MATL, ma penso che i metodi siano abbastanza diversi, quindi ho ancora pubblicato questo.
David,

Adoro la convoluzione!
Luis Mendo il

Puoi salvare un po 'cambiando [1 1]in TTo. Inoltre, non è necessaria la virgola
Luis Mendo il

@LuisMendo grazie! Pensavo che ci fosse stato un modo migliore per farlo!
David, il

Ora vedo come funziona la convoluzione qui. L'uso della denominazione a 0 delle carte è stato molto intelligente!
Luis Mendo il

0

Mathematica, 93 92 91 byte

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

Stai ancora cercando un modulo chiuso ...


implicherà un ciclo nidificato di calcoli di permutazione.
Sparr,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.