File Coverage

blib/lib/Math/Permute/Array.pm
Criterion Covered Total %
statement 83 84 98.8
branch 14 14 100.0
condition 6 6 100.0
subroutine 11 11 100.0
pod 9 9 100.0
total 123 124 99.1


line stmt bran cond sub pod time code
1             package Math::Permute::Array;
2              
3 5     5   154548 use strict;
  5         11  
  5         210  
4 5     5   29 use warnings;
  5         13  
  5         5844  
5              
6             require Exporter;
7              
8             our @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 Math::Permute::Array ':all';
15             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
16             # will save memory.
17             our %EXPORT_TAGS = ( 'all' => [ qw()],
18             'Permute' => [ qw(Permute) ],
19             'Apply_on_perms' => [ qw(Apply_on_perms) ]
20             );
21              
22             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
23              
24             our @EXPORT = qw(
25             Permute
26             Apply_on_perms
27             );
28              
29             our $VERSION = '0.043';
30              
31              
32             sub new
33             {
34 4     4 1 119 my $class = shift;
35 4         11 my $self = {};
36 4         13 $self->{array} = shift;
37 4         11 $self->{iterator} = 0;
38 4         10 $self->{cardinal} = undef;
39 4         12 bless($self, $class);
40 4 100       45 return undef unless (defined $self->{array});
41 3         11 return $self;
42             }
43              
44             #nice implementation from the cookbook
45             #but mine seems lightly more efficient
46             #sub N2Permute
47             #{
48             # my $rank = shift;
49             # my $size = shift;
50             # my @res;
51             #
52             # my $i=1;
53             # while($i<=$size){
54             # push @res, $rank % ($i);
55             # $rank = int($rank / ($i));
56             # $i++;
57             # }
58             # return @res;
59             #}
60              
61             sub Permute
62             {
63 80643     80643 1 117533 my $rest = shift;
64 80643         111047 my $array = shift;
65 80643 100 100     511348 return undef unless (defined $rest and defined $array);
66 80640         109015 my @array = @{$array};
  80640         247900  
67 80640         118446 my @res;
68              
69             # my $size = $#$array+1;
70             # my @perm = N2Permute($k,$size);
71             #push @res, splice(@array, (pop @perm), 1 )while @perm;
72              
73 80640         120524 my $i = 0;
74 80640         225126 while($rest != 0){
75 506558         1250720 $res[$i] = splice @array, $rest % ($#array + 1), 1;
76 506558         995963 $rest = int($rest / ($#array + 2));
77 506558         1256682 $i++;
78             }
79 80640         167314 push @res, @array;
80              
81 80640         400702 return \@res;
82             }
83              
84             sub permutation
85             {
86 7     7 1 34 my $self = shift;
87 7         13 my $rest = shift;
88 7 100       18 return undef unless (defined $rest);
89 6         16 my @array = @{$self->{array}};
  6         17  
90 6         8 my @res;
91 6         7 my $i = 0;
92 6         15 while($rest != 0){
93 8         18 $res[$i] = splice @array, $rest % ($#array + 1), 1;
94 8         15 $rest = int($rest / ($#array + 2));
95 8         159 $i++;
96             }
97 6         9 push @res, @array;
98 6         25 return \@res;
99             }
100              
101             sub Apply_on_perms(&@)
102             {
103 4     4 1 45 my $func = shift;
104 4         6 my $array = shift;
105 4 100 100     37 return undef unless (defined $func and defined $array);
106 1         3 my $rest;
107             my $i;
108 0         0 my $j;
109 1         3 my @array = @{$array};
  1         4  
110 1         2 my $size = $#array+1;
111 1         6 my $card = factorial($size);
112 1         2 my @res;
113 1         4 for($j=0;$j<$card;$j++){
114 40320         70103 @res = ();
115 40320         56046 $rest = $j;
116 40320         45467 $i = 0;
117 40320         88398 while($rest != 0){
118 253279         557732 $res[$i] = splice @array, $rest % ($#array + 1), 1;
119 253279         504280 $rest = int($rest / ($#array + 2));
120 253279         597671 $i++;
121             }
122 40320         75593 push @res, @array;
123 40320         140977 &$func(@res);
124 40320         128380 @array = @{$array};
  40320         238943  
125             }
126 1         7 return 0;
127             }
128              
129             sub cur
130             {
131 2     2 1 12 my $self = shift;
132 2         9 return Math::Permute::Array::Permute($self->{iterator},$self->{array});
133             }
134              
135             sub prev
136             {
137 40320     40320 1 166416 my $self = shift;
138 40320 100       121527 return undef if($self->{iterator} == 0);
139 40319         62937 $self->{iterator}--;
140 40319         97485 return Math::Permute::Array::Permute($self->{iterator},$self->{array});
141             }
142              
143             sub next
144             {
145 40320     40320 1 220366 my $self = shift;
146 40320 100       107271 return undef if($self->{iterator} >= $self->cardinal() - 1);
147 40319         78248 $self->{iterator}++;
148 40319         111746 return Math::Permute::Array::Permute($self->{iterator},$self->{array});
149             }
150              
151             sub cardinal
152             {
153 40322     40322 1 77870 my $self = shift;
154 40322 100       115113 unless(defined $self->{cardinal}){
155 2         4 $self->{cardinal} = factorial($#{$self->{array}} + 1);
  2         14  
156             }
157 40322         162870 return $self->{cardinal};
158             }
159              
160             #this part come from:
161             # www.theperlreview.com/SamplePages/ThePerlReview-v5i1.p23.pdf
162             # Author: Alberto Manuel Simoes
163             sub factorial
164             {
165 3     3 1 9 my $value = shift;
166 3         8 my $res = 1;
167 3         18 while ($value > 1) {
168 16         20 $res *= $value;
169 16         37 $value--;
170             }
171 3         22 return $res;
172             }
173              
174             1;
175              
176             __END__