Velocity Reviews > Perl > splitting an array

# splitting an array

debraj
Guest
Posts: n/a

 09-06-2003
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

Lao Coon
Guest
Posts: n/a

 09-06-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) (debraj) wrote in
news:(E-Mail Removed) m:

> 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

Jay Tilton
Guest
Posts: n/a

 09-06-2003
(E-Mail 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";

Jay Tilton
Guest
Posts: n/a

 09-06-2003
(E-Mail Removed) (Jay Tilton) wrote:

: (E-Mail 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?

Guest
Posts: n/a

 09-07-2003
On Sat, 06 Sep 2003 03:18:25 -0400, 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 .

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"), (@_ && _(@_));
}

Philip Lees
Guest
Posts: n/a

 09-08-2003
On Sat, 06 Sep 2003 23:05:29 GMT, (E-Mail 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?

Phil

--
Ignore coming events if you wish to send me e-mail

Tassilo v. Parseval
Guest
Posts: n/a

 09-08-2003
Also sprach Philip Lees:

> On Sat, 06 Sep 2003 23:05:29 GMT, (E-Mail 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/>.

Tassilo
--
\$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_\$;//::niam/s~=)]3[))_\$-3(rellac(=_\$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
\$_=reverse,s+(?<=sub).+q#q!'"qq.\t\$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval

Jay Tilton
Guest
Posts: n/a

 09-09-2003
"Tassilo v. Parseval" <(E-Mail Removed)> wrote:

: Also sprach Philip Lees:
:
: > On Sat, 06 Sep 2003 23:05:29 GMT, (E-Mail 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....of-the-week/43

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

Anno Siegel
Guest
Posts: n/a

 09-12-2003
LaDainian Tomlinson <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> On Sat, 06 Sep 2003 03:18:25 -0400, 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 .

>
> 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, \$_, = 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