Skip to content

Instantly share code, notes, and snippets.

@masak
Last active December 10, 2015 13:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save masak/4443780 to your computer and use it in GitHub Desktop.
Save masak/4443780 to your computer and use it in GitHub Desktop.
What's the expected loop length of a randomly chosen mapping from 1..N to 1..N?
my $MAX_N = 20;
my $TRIALS = 10_000;
for 1 .. $MAX_N -> $N {
my @lengths = loop-length(random-mapping($N)) xx $TRIALS;
my $average = ([+] @lengths) / @lengths;
my $analytical = analytical($N);
my $percent_error = abs($analytical - $average) / $analytical * 100;
FIRST say " N average analytical (error)";
FIRST say "=== ========= ============ =========";
my @columns =
$N.fmt('%3d'),
$average.fmt('%9.4f'),
$analytical.fmt('%12.4f'),
$percent_error.fmt(' (%2d%%)'),
;
say join ' ', @columns;
}
sub random-mapping($size) {
# Not just a permutation, but a mapping from all 1..N to any 1..N
# In other words, .roll, not .pick
return hash map { $_ => (1..$size).roll }, 1..$size;
}
sub loop-length(%mapping) {
my %seen;
my $current = 1;
my $steps = 0;
while !%seen{$current}++ {
$current = %mapping{$current};
$steps++;
}
return $steps;
}
sub analytical($N) {
sub postfix:<!>($n) { [*] 1..$n }
return [+] (1..$N).map: -> $k { $N! * $k * $k / $N ** ($k + 1) / ($N - $k)! };
}
N average analytical (error)
=== ========= ============ =========
1 1.0000 1.0000 ( 0.00%)
2 1.4992 1.5000 ( 0.05%)
3 1.8784 1.8889 ( 0.56%)
4 2.2316 2.2188 ( 0.58%)
5 2.4982 2.5104 ( 0.49%)
6 2.7897 2.7747 ( 0.54%)
7 3.0153 3.0181 ( 0.09%)
8 3.2429 3.2450 ( 0.07%)
9 3.4536 3.4583 ( 0.14%)
10 3.6649 3.6602 ( 0.13%)
11 3.8091 3.8524 ( 1.12%)
12 3.9986 4.0361 ( 0.93%)
13 4.2074 4.2123 ( 0.12%)
14 4.3711 4.3820 ( 0.25%)
15 4.5275 4.5458 ( 0.40%)
16 4.6755 4.7043 ( 0.61%)
17 4.8877 4.8579 ( 0.61%)
18 4.9951 5.0071 ( 0.24%)
19 5.1312 5.1522 ( 0.41%)
20 5.2699 5.2936 ( 0.45%)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment