splitting an array

D

debraj

Hi All ,

I have one array of numbers say (12 17 18 19 120 121 122 123 124 379
480 481).
Now I want to get the starting and ending of any cosecutive numbers
from this array .
For eg. result should be (12--12,17--19,120--124,379--379,480--481) .
Note that if a number without any sequence is present it will be
printed in the format 12--12 .

Thanx
debhatta
 
L

Lao Coon

(e-mail address removed) (debraj) wrote in
Hi All ,

I have one array of numbers say (12 17 18 19 120 121 122 123 124 379
480 481).
Now I want to get the starting and ending of any cosecutive numbers
from this array .
For eg. result should be (12--12,17--19,120--124,379--379,480--481) .
Note that if a number without any sequence is present it will be
printed in the format 12--12 .

One way:

my @list = (12,17,18,19,120,121,122,123,123,379,480,481);
my @res;
for(my $i = $j = 0; $i < @list; $i++) {
$j++ if $i && $list[$i] != $list[$i-1]+1;
push @{$res[$j]}, $list[$i];
}

HTH
Lao
 
J

Jay Tilton

(e-mail address removed) (debraj) wrote:

: I have one array of numbers say (12 17 18 19 120 121 122 123 124 379
: 480 481).
: Now I want to get the starting and ending of any cosecutive numbers
: from this array .
: For eg. result should be (12--12,17--19,120--124,379--379,480--481) .
: Note that if a number without any sequence is present it will be
: printed in the format 12--12 .

my @ary = (12,17,18,19,120,121,122,123,124,379,480,481);
my $seqs = join ',', map "$_--$_", sort {$a <=> $b} @ary;
1 while $seqs =~ s/(\d+),(??{$1+1})--(\d+)/$2/;
print "($seqs)\n";
 
J

Jay Tilton

(e-mail address removed) (Jay Tilton) wrote:

: (e-mail address removed) (debraj) wrote:
:
: : I have one array of numbers say (12 17 18 19 120 121 122 123 124 379
: : 480 481).
: : Now I want to get the starting and ending of any cosecutive numbers
: : from this array .
: : For eg. result should be (12--12,17--19,120--124,379--379,480--481) .
: : Note that if a number without any sequence is present it will be
: : printed in the format 12--12 .
:
: my @ary = (12,17,18,19,120,121,122,123,124,379,480,481);
: my $seqs = join ',', map "$_--$_", sort {$a <=> $b} @ary;
: 1 while $seqs =~ s/(\d+),(??{$1+1})--(\d+)/$2/;
: print "($seqs)\n";

Or, using an actual data structure instead of a string,

my @ary = (12,17,18,19,120,121,122,123,124,379,480,481);
my @seqs = map [$_, $_], sort {$a <=> $b} @ary;
$seqs[$_-1][1] = (splice @seqs, $_, 1)[0]->[1]
for grep $seqs[$_-1][1] == $seqs[$_][0]-1 => reverse 1..$#seqs;
print join ',' => map sprintf('%d--%d', @$_), @seqs;

Kinda fun. I remember seeing variations on this problem solved before on
clpm, but I couldn't hit on the right Google Groups search terms. Any
pointers?
 
L

LaDainian Tomlinson

I have one array of numbers say (12 17 18 19 120 121 122 123 124 379 480
481).
Now I want to get the starting and ending of any cosecutive numbers from
this array .
For eg. result should be (12--12,17--19,120--124,379--379,480--481) .
Note that if a number without any sequence is present it will be
printed in the format 12--12 .

This may not help much, but it works for your case and I learned a lot :)


_(qw.12 17 18 19 120 121 122 123 124 379 480 481.);
sub _{
print($_ = shift);
while(@_){ ($_[0] == $_ + 1) ? $_ = shift : last; }
print("--$_\n"), (@_ && _(@_));
}
 
P

Philip Lees

Kinda fun. I remember seeing variations on this problem solved before on
clpm, but I couldn't hit on the right Google Groups search terms. Any
pointers?

Wasn't it one of MJDs quizzes of the week?

Phil
 
J

Jay Tilton

: Also sprach Philip Lees:
:
: > On Sat, 06 Sep 2003 23:05:29 GMT, (e-mail address removed) (Jay Tilton)
: > wrote:
: >
: >>Kinda fun. I remember seeing variations on this problem solved before on
: >>clpm, but I couldn't hit on the right Google Groups search terms. Any
: >>pointers?
: >
: > Wasn't it one of MJDs quizzes of the week?
:
: Yes, it was some time ago. The related archive of discussions can
: probably be found somewhere at <http://perl.plover.com/qotw/>.

Found it.
http://article.gmane.org/gmane.comp.lang.perl.qotw.quiz-of-the-week/43

And naturally there's a module squirrelled away on CPAN that does the
job.
 
A

Anno Siegel

LaDainian Tomlinson said:
I have one array of numbers say (12 17 18 19 120 121 122 123 124 379 480
481).
Now I want to get the starting and ending of any cosecutive numbers from
this array .
For eg. result should be (12--12,17--19,120--124,379--379,480--481) .
Note that if a number without any sequence is present it will be
printed in the format 12--12 .

This may not help much, but it works for your case and I learned a lot :)


_(qw.12 17 18 19 120 121 122 123 124 379 480 481.);
sub _{
print($_ = shift);
while(@_){ ($_[0] == $_ + 1) ? $_ = shift : last; }
print("--$_\n"), (@_ && _(@_));
}

Here is a solution based on matching and substitution:

sub trans {
my $str = '';
vec( $str, $_, 8) = ord '1' for @_; # any char except "\0"
$str =~ s/1+/"$-[ 0]-" . ($+[ 0] - 1)/eg;
split /\0+/, $str;
}

For this the original list doesn't have to be sorted.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top