File Coverage

blib/lib/DoubleBlind.pm
Criterion Covered Total %
statement 40 40 100.0
branch 9 10 90.0
condition 4 5 80.0
subroutine 6 6 100.0
pod 1 3 33.3
total 60 64 93.7


line stmt bran cond sub pod time code
1             package DoubleBlind;
2              
3 1     1   39843 use 5.005;
  1         4  
  1         46  
4 1     1   8 use strict;
  1         2  
  1         71  
5              
6             require Exporter;
7 1     1   6 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         15  
  1         941  
8             @ISA = qw(Exporter);
9              
10             # Items to export into callers namespace by default. Note: do not export
11             # names by default without a very good reason. Use EXPORT_OK instead.
12             # Do not simply export all your public functions/methods/constants.
13              
14             # This allows declaration use DoubleBlind ':all';
15             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
16             # will save memory.
17             %EXPORT_TAGS = ( 'all' => [ qw(
18            
19             ) ] );
20              
21             @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
22              
23             @EXPORT = qw(
24            
25             );
26              
27             $VERSION = '0.01';
28              
29             # Preloaded methods go here.
30              
31             sub shuffle ($;$) {
32 3     3 0 743 my ($n, $s) = (shift, shift);
33 3 100       12 defined $s or $s = 1;
34 3         14 my @out = ($s .. $s+$n-1);
35 3         8 while ($n) { # Unshuffled stuff is at indices 0..$n-1
36 13         69 my $pick = int rand $n--;
37 13         35 @out[$n, $pick] = @out[$pick, $n];
38             }
39 3         9 \@out;
40             }
41              
42             # A good number is: square between 3000000 and 9999999, it has no zeros,
43             # digits (up to 0.001) are repeated no more than twice,
44             # last N digits of the square are as requested, fractional part of the
45             # square is between 0.2 and 0.8 (to avoid rounding errors)
46              
47             sub good_number ($;$) {
48 4     4 0 192 my ($targ, $N) = (shift, shift);
49 4 50       11 defined $N or $N = 1;
50 4         6 my $s = 1 + int sqrt 3000000;
51 4         4 my $e = int sqrt 9699999;
52 4         15 my $R = int(0.5 + 10**$N);
53 4030         17169 picking:
54 4         5 { my $pick = sprintf '%.3f', $s + rand $e - $s;
55 4030 100       10373 redo if $pick =~ /0/;
56 2068         3480 my $a = $pick**2;
57 2068         2562 my $f = $a - int $a;
58 2068 100 100     8099 redo if $f < 0.2 or $f > 0.8;
59             #warn "T $pick ==> $a\n";
60 1217         1425 my $ai = int $a;
61 1217 100       2878 redo unless $ai - $R*int($ai/$R) == $targ;
62             #warn "Try $pick ==> $a\n";
63 4         6 my %seen;
64 4   50     91 ++$seen{$_} <= 2 or redo picking for split //, $pick;
65             #warn "Got $pick ==> $a\n";
66 4         26 return $pick;
67             }
68             }
69              
70             sub process_shuffled ($$$) {
71 1     1 1 448 my ($callback, $c, $start) = (shift,shift,shift);
72             #defined $start or $start = ($c =~ /^10+$/ ? 0 : 1);
73 1         5 my $len = length($start + $c - 1);
74 1         4 my $l = shuffle $c, $start;
75 1         5 for my $n (0..$#$l) {
76 3         428 my $label = good_number $l->[$n], $len;
77 3         15 $callback->($n+1, $l->[$n], $label);
78             }
79 1         274 $l = $start + $c - 1;
80 1         127 <
81             $c items generated. Each item numbers has a "secret" id ($start to $l),
82             and a "public" label (which is a number about 2000 with 3 digits after
83             the decimal dot - or the decimal comma). To extract the id from the label,
84             calculate the square of the label, and take the last $len digits before the
85             decimal dot (or the decimal comma).
86             EOD
87             }
88              
89              
90             1;
91             __END__