卡对概率


9

给定一个卡片组,其中N张卡片由N个卡片组成,其中N个卡片的整数值为[ 1M ],总共N * M张卡片,计算出值为1的卡片与值为2的卡片相邻的概率。

您的解决方案可能是精确的或近似的,并且在给定相同输入的情况下,每次运行都不必相同。给定的答案应在真实解决方案的+/- 5%之内(除非RNG不太可能对您不利)。您的程序应在合理的时间内给出答案(例如,使用任何硬件不到10分钟)。您可以假设MN合理小,并且不需要进行错误检查。

卡组不是周期性的,因此如果第一张卡为1,最后一张卡为2,则这不满足邻接要求。

作为测试用例,对于N = 4M = 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

输出可以采用您认为方便的任何形式(函数返回值,终端输出,文件等),而输入可以采用您认为方便的任何形式(函数参数,终端输入,命令行arg等)。

适用标准孔。

这是代码高尔夫球,最短的代码(以字节为单位)获胜。

排行榜


1
邻接不环绕是看似复杂的扭曲
Sparr

@Sparr你给我一个主意!:-)
路易斯·门多

Answers:


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

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

注意(16/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答案,但是我认为方法完全不同,因此我仍然发布了这个答案。
戴维(David)

我爱卷积!
Luis Mendo 2015年

您可以保存一些更改[1 1]TTo。此外,您不需要逗号
路易斯Mendo

@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&

仍在寻找封闭表格...


它会涉及到排列计算的嵌套循环。
Sparr 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.