Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

array of arrays or not

by coldy (Scribe)
on Feb 23, 2009 at 07:08 UTC ( [id://745714]=perlquestion: print w/replies, xml ) Need Help??

coldy has asked for the wisdom of the Perl Monks concerning the following question:

I have two arrays, representing start and stop positions for a sequence,
@a=(1,15,30,50,65) @b=(5,20,37,55,77)
so for example, the first elements of each array (1 and 5) represent the numbers 1,2,3,4,5; the two arrays define the numbers 1,2,3,..5,15,16,..,20,...,65,66,...,77) Now, I also have two scalars, say, $s1=9, $s2=35, where these also represent a range of integers 9,10,11,..,35. The problem is to find the numbers defined by @a and @b which intersect with the range defined by $s1 and $s2.

I tend to things the long way in perl, so I thought of creating an array of arrays

@AoA=([1,5],[15,20],...,[65,77]) <p>
then finding the intersection of ($s1..$s2) with each of the array elements.

If anybody can think of a better way to do this, any help much appreciated, otherwise, a good way to create the array of array would also be appreciated.

Thanks in advance!

Replies are listed 'Best First'.
Re: array of arrays or not
by BrowserUk (Patriarch) on Feb 23, 2009 at 07:21 UTC

    It's one reasonably efficient line using the data as you currently have it:

    #! perl -slw use strict; my @a = ( 1, 15, 30, 50, 65 ); my @b = ( 5, 20, 37, 55, 77 ); my( $s1, $s2 ) =( 9, 35 ); my @result = map{ grep $_ >= $s1 && $_ <= $s2, $a[ $_ ] .. $b[ $_ ] } 0 .. $#a; print "@result"; __END__ C:\test>junk12 15 16 17 18 19 20 30 31 32 33 34 35

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: array of arrays or not
by ysth (Canon) on Feb 23, 2009 at 07:45 UTC
Re: array of arrays or not
by tilly (Archbishop) on Feb 23, 2009 at 07:57 UTC
    If your intervals are potentially long, then I'd suggest the array of array approach because it avoids constructing long lists of elements. You can produce that array of arrays with:
    my @interval_arrays = map [$a[$_], $b[$_]], 0..$#a;
    And then you can intersect with your interval and get a result in the same format with:
    my @intersected_arrays = map { my $min = $s1 < $_->[0] ? $_->[0] : $s1; my $max = $s2 > $_->[1] ? $_->[1] : $s2; $min <= $max ? [$min, $max] : (); } @interval_arrays;
Re: array of arrays or not
by CountZero (Bishop) on Feb 23, 2009 at 09:51 UTC
    Perhaps a module such as Number::Interval, Set::Window or Set::IntRange can assist.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: array of arrays or not
by poolpi (Hermit) on Feb 23, 2009 at 10:51 UTC
    #!/usr/bin/perl use strict; use warnings; use Set::IntSpan; use Data::Dumper; my $set1 = new Set::IntSpan "1-5, 15-20, 30-35, 50-55, 65-70"; my $set2 = new Set::IntSpan "9-35"; my $i_set = $set2 * $set1; my $inter = elements $i_set; print Dumper $inter; __END__ Output: ------ $VAR1 = [ 15, 16, 17, 18, 19, 20, 30, 31, 32, 33, 34, 35 ];


    hth,
    PooLpi

    'Ebry haffa hoe hab im tik a bush'. Jamaican proverb

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://745714]
Approved by Corion
Front-paged by ysth
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-04-19 01:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found