Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Speeding permutation counting

by blokhead (Monsignor)
on Jul 18, 2007 at 14:26 UTC ( [id://627258]=note: print w/replies, xml ) Need Help??


in reply to Speeding permutation counting

I think the previous replies have misunderstood your question. If I understand correctly, you want to take a pair of strings, put them on top of each other, and read *down* the columns:
string A: 0 1 0 1 string B: 1 1 0 1 | | | | | | | +--> 11 | | +----> 00 | +------> 11 +--------> 01
.. i.e, not just look at all the pairs of characters in an individual string..

Splitting each string into an array seems wasteful, as arrays are much more memory-heavy than strings. You can use substr to index into any position in the string to get individual characters.

Also, instead of 4 different cases of logic involving 4 similarly-named variables $c00 through $c11, you can use a hash to really simplify the code:

my @data = qw[ 111011001010011110100010100001 111010000010010110000010000001 000101011100001000110101110000 000101111101001001111101111110 111011001010111110100010100001 000100010100000000010001010000 ]; use Data::Dumper; for my $i (0 .. $#data) { for my $j ($i+1 .. $#data) { my %counts; $counts{ substr($data[$i],$_,1) . substr($data[$j],$_,1) }++ for 0 .. length($data[$i]) - 1; print Dumper \%counts; } }
Another cute solution is to use chop to trim off characters at a time from both strings. It generates these character-pairs in reverse order, but since you only care about the final count, it's ok. Since it modifies the string, you have to do it on a copy.
for my $i (0 .. $#data) { for my $j ($i+1 .. $#data) { my %counts; my ($str1, $str2) = @data[$i,$j]; $counts{ chop($str1) . chop($str2) }++ while length($str1) and length($str2); print Dumper \%counts; } }

blokhead

Replies are listed 'Best First'.
Re^2: Speeding permutation counting
by albert (Monk) on Jul 18, 2007 at 14:57 UTC
    Yes, this is the correct interpretation of my question, and thanks for your suggestions. I benchmarked your two suggestions relative to my original, and things are definitely improved:
    Rate orig substring blokhead blokchop orig 1199/s -- -45% -62% -69% substring 2162/s 80% -- -31% -44% blokhead 3144/s 162% 45% -- -18% blokchop 3840/s 220% 78% 22% --
    "Substring" is closer to my original (too verbose) style, so some of the gains are also coming from the more succinct, easier to read code. Best so far is the "chop" based suggestion.

    Still wondering if there might be other improvements, or some vastly different way to solve this.

    Thanks for these suggestions, they really have helped.
    -a

      Do you have the benchmark code? I consider benchmark results useless without the accompanying benchmark code.

      It's also stopping us from comparing our own solutions without redoing all your work.

      If you're worried about the space it takes, use <readmore> or <spoiler> tags.

        Yeah, it was a space concern. Took things right from the solutions, and code includes other things I was testing (and your suggestion as well).

        Details...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://627258]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-25 12:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found