Вероятность пары карт


9

Учитывая колоду, состоящую из N копий карт с целочисленными значениями [ 1 , M ] для общего количества N * M карт, вычислите вероятность того, что карта со значением 1 смежна с картой со значением 2 .

Ваше решение может быть точным или приблизительным, и оно не обязательно должно быть одинаковым для каждого прогона при одинаковых входных данных. Данный ответ должен быть в пределах +/- 5% от истинного решения (исключая очень редкие шансы, что ГСЧ не в вашу пользу). Ваша программа должна дать ответ в течение разумного периода времени (скажем, менее 10 минут на любом оборудовании, которое у вас есть). Вы можете предположить, что M и N достаточно малы и проверка ошибок не требуется.

Колода не является циклической, поэтому, если первая карта - 1, а последняя - 2 , это не соответствует требованиям смежности.

Например, для N = 4 и M = 13 (стандартная колода из 52 карт) ожидаемое решение составляет ~ 48,6%.

Вот пример реализации без игры в гольф в Python + NumPy с использованием случайных перемешиваний:

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

Вывод может быть в любой удобной для вас форме (возвращаемое значение функции, вывод терминала, файл и т. Д.), А ввод может быть в любой удобной для вас форме (параметр функции, ввод терминала, аргумент командной строки и т. Д.)

Применяются стандартные петли.

Это код гольф, выигрывает самый короткий код (в байтах).

Leaderboard


1
Смежность без обмана - обманчиво сложный поворот
Sparr

@Sparr Вы дали мне идею! :-)
Луис Мендо

Ответы:


2

Pyth, 23 22 байта

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

Запускает 10000 итераций. Число может быть изменено без стоимости байта. Ввод разделен новой строкой. Занимает около 9 секунд на моем компьютере.

демонстрация

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 байтов

При этом используется версия 3.1.0 языка, которая является более ранней, чем эта проблема.

Вычисление выполняется с помощью цикла, который рисует 1000 случайных реализаций. Это займет пару секунд, чтобы бежать. Это может быть сделано быстрее в векторизованном виде. Вход имеет форму [N M].

Старая версия : генерирует случайную колоду карт и проверяет ее дважды: сначала в прямом, а затем в обратном направлении.

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

Новая версия : генерирует случайную колоду карт, а затем добавляет перевернутую версию с 0промежуточным символом. Таким образом, проверка может быть выполнена только один раз в прямом направлении. Это экономит два байта.

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

пример

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

объяснение

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 байт

JE?>J1-1^-1c2JQZ

Демонстрация.

Это следует за

  • сделать обоснованное предположение,
  • проверьте, что это достаточно близко,
  • повторение

стратегия программирования. Победное обоснованное предположение в этом случае

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

что примерно говорит о том, что есть Nшансы попасть в ведра, а доля действительных ведер есть 2 / M. Ведра, являющиеся слотами, располагаются рядом с 0s, а шансы - 1s.

Кажется, что ошибка никогда не превышает 3% (на удивление), и, похоже, сходится к 0%, когда параметры становятся больше (как я и ожидал).

Ввод разделен новой строкой.

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

Вы можете сохранить персонажа, если вы примете очевидный факт False == 0, и сделайте JE&>J1-1^-1c2JQвместо этого.


Это мой первый опыт в Pyth (и мой первый ответ), поэтому критика и помощь особенно приветствуются.
Veedrac

1

MATL , 44 38 байт

При этом также используется версия MATL 3.1.0 , которая является более ранней, чем эта задача.

Новая версия, спасибо Луису Мендо за сохранение 4 байта!

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

Старая версия (44 байта):

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

объяснение

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

Например,

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

Примечание (21/5/16): Начиная с выпуска MATL 18.0.0, X+оно было удалено, но Y+может использоваться вместо него. Изменения с версии MATL 3.1.0 до 18.0.0 означают, что этот ответ теперь может быть записан всего 31 байтом *xO1e4:"2:Gtb*Z@w\TT2&Y+1=ah]Ym.


Я знаю, что уже есть ответ MATL, но я думаю, что методы совершенно разные, поэтому я все еще опубликовал этот.
Дэвид

Я люблю свертки!
Луис Мендо

Вы можете сэкономить немного меняется [1 1]в TTo. Кроме того, вам не нужна запятая
Луис Мендо

@ LuisMendo спасибо! Я думал, что должен быть лучший способ сделать это!
Дэвид

Теперь я вижу, как здесь работает свертка. Использование именования на основе 0 было очень умным!
Луис Мендо

0

Mathematica, 93 92 91 байт

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

Все еще ищу закрытую форму ...


это будет включать в себя вложенный цикл вычислений перестановки.
Спарр
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.