Running the inner loop forward ensure earliest short-circuit and cut time to 1/4.
This will work regardless of the data and takes just under 2 minutes 35 seconds for a maximum sized AoA.
#! perl -slw
use strict;
use Time::HiRes qw[ time ];
use Data::Dump qw[ pp ];
## Generate test data
my @paths = map[ map chr(65+rand 26), 2 .. 2+rand(11) ], 1 .. 32448;
my $start = time;
## Sort by length of subarray; shortest last to facilitate deletion in
+ a loop
@paths = sort{ $#{ $b } <=> $#{ $a } } @paths;
#pp \@paths;
## Build an index to the elements in all the subarrays
my( $i, %index ) = 0;
for my $ref ( @paths ){
$index{ $_ } //= ++$i for @$ref;
}
#pp \%index;
## Use the index to build bitmaps representing the subarrays
my @bitmaps = ( '' ) x @paths;
for my $n ( 0 .. $#paths ) {
vec( $bitmaps[ $n ], $index{ $_ }, 1 ) = 1 for @{ $paths[ $n ] };
}
#pp \@bitmaps;
## bitwise OR the bitmaps to discover wholly contained subarrays and r
+emove them
OUTER:for my $i ( reverse 0 .. $#paths ) {
for my $j ( 0 .. $i-1 ) { ## Remove rev
+erse; short-circuit earlier.
if( ( $bitmaps[ $j ] | $bitmaps[ $i ] ) eq $bitmaps[ $j ] ) {
# warn "deleting $i";
delete $paths[ $i ];
next OUTER;
}
}
}
## remove undefs
@paths = grep defined, @paths;
printf "Deleted %u subarrays\n", 32448 - @paths;
printf "Took %.6f seconds\nEnter to see results:", time() - $start;
<STDIN>;
pp \@paths;
__END__
C:\test>1169736.pl
Deleted 22228 subarrays
Took 107.267549 seconds
Enter to see results:Terminating on signal SIGINT(2)
C:\test>1169736.pl
Deleted 22024 subarrays
Took 108.820184 seconds
Enter to see results:Terminating on signal SIGINT(2)
It works by building an index to the items in the subarrays; uses that index to build bitmaps representing the subarrays; the cross compares the bitmaps using bitwise-OR to determine wholly contained subarrays and deletes them.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|