カードペア確率


9

整数値[ 1M ] のカードのNコピーで構成されるデッキの合計がN * Mのカードである場合、値が1のカードが値が2のカードに隣接している確率を計算します。

ソリューションは正確または近似であり、同じ入力が与えられたすべての実行で同じである必要はありません。与えられた答えは、真のソリューションの+/- 5%以内である必要があります(RNGが不利になる可能性は非常にまれです)。プログラムは、妥当な時間内(たとえば、使用しているハードウェアでは10分未満)で答えを出す必要があります。MNは妥当な小ささで、エラーチェックは必要ないと思われるかもしれません。

デッキは循環的ではないため、最初のカードが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

出力は、便利な任意の形式(関数の戻り値、端末出力、ファイルなど)で、入力は、便利な任意の形式(関数パラメーター、端末入力、コマンドライン引数など)でかまいません。

標準の抜け穴が適用されます。

これはコードゴルフで、最短のコード(バイト単位)が勝ちます。

リーダーボード


1
隣接しないラップアラウンドは
一見

@Sparrあなたは私にアイデアを与えました!:-)
Luis Mendo

回答:


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]です。

古いバージョン:カードのランダムなデッキを生成し、それを2回チェックします。最初は順方向、次に逆方向です。

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

新しいバージョン:ランダムなカードのデッキを生成し、0その間に反転バージョンを追加します。このようにして、チェックは順方向に1回だけ実行できます。これにより2バイトが節約されます。

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、2015

1

MATL44 38バイト

これは、この課題よりも前のMATL バージョン3.1.0も使用します。

新しいバージョン、Luis Mendoによる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の回答があることは知っていますが、方法はかなり異なると思うので、まだこれを投稿しました。
デビッド

たたみ込みが大好きです。
Luis Mendo 2015

に変更[1 1]を少し保存できますTTo。また、コンマは必要ありません
Luis Mendo

@LuisMendoありがとう!それを行うにはもっと良い方法があるに違いないと思いました!
デビッド

ここで、畳み込みがどのように機能するかを確認します。カードの0ベースのネーミングを使用することは非常に賢明でした!
Luis Mendo

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&

まだ閉じたフォームを探しています...


これには、入れ替え計算のネストされたループが含まれます。
Sparr、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.