一个简单的问题一直困扰着我,我不知道如何做数学来证明它,所以我编写了一个简单的Perl程序来近似一个答案,我只是不同意它的结果。
是我错了,还是我的脚本缺少了什么?
问题
10双相同的袜子,除了左边或右边。如果是随机配对,正确配对和不正确配对的概率是多少?
更新
我的意思是,如果蒙上眼睛,我把抽屉里的20双袜子都配对了,正确的对和不对的成对的比例是多少?
我的脚本指出大约1.12比1正确的比率不正确。
是对的吗?
#!/usr/bin/perl
#SockCruncher
#use strict;
use warnings;
use List::Util 'shuffle';
my @tumble_dryer = (R,R,R,R,R,R,R,R,R,R,L,L,L,L,L,L,L,L,L,L);
my @rand_socks = shuffle(@tumble_dryer);
my $sock_pop1;
my $sock_pop2;
my $pair_counter = 1;
my @rev_rand_socks;
my $good_pair = 0;
my $bad_pair = 0;
my $counter = 0;
open (OUT,'>pairing.txt') or die ("Can't open pairing.txt for writing\n");
print OUT "Sock Sorter\n-----------\n\n";
print OUT "10 pairs of socks all identical appart from them being either left or right. 10 left & 10 right.\n";
print OUT "The 20 socks are shuffled in an array and the first 2 popped out.\n";
print OUT "The remaining socks are shuffled again and the first 2 popped out..... and so on.\n\n";
while ($counter < 100000) {
while ($pair_counter <= 10) {
print OUT "Socks : ";
print OUT join(",", @rand_socks);
@rev_rand_socks = reverse @rand_socks; #Just done so the output file looks better. The LHS 2 elements are popped and eventually spliced off.
$sock_pop1 = pop @rev_rand_socks;
$sock_pop2 = pop @rev_rand_socks;
print OUT " (P$pair_counter : $sock_pop1.$sock_pop2) ";
if (($sock_pop1 eq "L") && ($sock_pop2 eq "R")) {$good_pair = $good_pair +1;}
if (($sock_pop1 eq "R") && ($sock_pop2 eq "L")) {$good_pair = $good_pair +1;}
if (($sock_pop1 eq "L") && ($sock_pop2 eq "L")) {$bad_pair = $bad_pair +1;}
if (($sock_pop1 eq "R") && ($sock_pop2 eq "R")) {$bad_pair = $bad_pair +1;}
splice @rand_socks, 0, 2;
@rand_socks = shuffle(@rand_socks);
$pair_counter = $pair_counter + 1;
}
print OUT " Good pairs : $good_pair Bad pairs : $bad_pair\n";
$counter = $counter + 1;
$pair_counter = 1;
@tumble_dryer = (R,R,R,R,R,R,R,R,R,R,L,L,L,L,L,L,L,L,L,L);
@rand_socks = shuffle(@tumble_dryer);
}
my $ratio = $good_pair/$bad_pair;
print "\nGood pairs = $good_pair Bad pairs = $bad_pair Good pair to bad pair ratio : $ratio.\n";
close (OUT);发布于 2018-08-21 15:10:04
假设你从抽屉里挑出一只R袜子。
现在只剩下10 L的袜子了(这样就可以做正确的配对)
剩下9只R袜子(不正确的配对)
所以10正确:9不正确大约是1.11:1。
您没有说明您预期的数字,但是如果您的脚本是1.12:1,则接近正确的结果。
发布于 2018-08-21 15:41:32
我猜问题是,如果你一次拔出所有的20双袜子,你多久会得到一双正确的袜子?但这当然不清楚,而且这也不是代码所做的。你似乎在你的内环中找到了好的对和坏的对,在内环之后,总有好的结果和坏的结果。
每次脱下袜子,都没有必要重新洗牌。
尝试在最小范围内声明变量。
FWIW我会这样做:
use strict;
use warnings;
use List::Util 'shuffle';
my $attempts = 1000000;
my $pairs = 10;
my @socks = (('R') x $pairs, ('L') x $pairs);
my $correct_pairings = 0;
for my $attempt (1..$attempts) {
my $picked_socks = join '', shuffle @socks;
++$correct_pairings if $picked_socks =~ /^(?:(.)\1){$pairs}/;
}
print "$correct_pairings correct pairings in $attempts attempts\n";这表明得到的匹配对比当时的.14%少10对。
https://stackoverflow.com/questions/51951628
复制相似问题