nandymamith has asked for the wisdom of the Perl Monks concerning the following question:
Can anybody help in getting the solution for me.
Below are the INPUT and the OUTPUT elements that I am expecting is as shown below :
INPUT
@array = ("1","2","3","5","6","7",9");
OUTPUT
@ranges = ("1:3","5:7","9");
Please Note: Do not use any CPAN libraries to extract the OUTPUT
Re: Generating ranges of numbers
by Anonymous Monk on Jun 30, 2016 at 10:09 UTC
|
Sounds like homework.
Can you describe the algorithm you would use in your own words?
But most importantly: Why is "1 2 3" turned into "1:3" but "5 6 7" turned into "5:6 7"? What rule does that follow?
| [reply] |
|
OUTPUT
@ranges = ("1:3","5:7","9");
| [reply] [d/l] |
Re: Generating ranges of numbers
by thezip (Vicar) on Jun 30, 2016 at 18:00 UTC
|
#!/usr/bin/perl
use strict;
use warnings;
use Set::IntSpan;
my @array = ("1", "2", "3", "5", "6", "7", "9");
my $set = Set::IntSpan->new(\@array);
my $out = join(',', $set->D($set->holes()));
print $out, "\n";
OUTPUT:
1-3,5-7,9
*My* tenacity goes to eleven...
| [reply] [d/l] [select] |
Re: Generating ranges of numbers
by choroba (Cardinal) on Jun 30, 2016 at 11:24 UTC
|
I changed the input and output to avoid the issue mentioned by Anonymous Monk.
#! /usr/bin/perl
use warnings;
use strict;
my @input = (1, 2, 3, 5, 6, 8, 10);
my @ranges = ($input[0]);
for my $i (1 .. $#input) {
warn "\t@ranges";
if ($input[ $i - 1 ] + 1 == $input[$i]) {
$ranges[-1] = (split /:/, $ranges[-1])[0] . ":$input[$i]";
} else {
push @ranges, $input[$i];
}
}
use Test::More tests => 1;
is_deeply \@ranges, [ '1:3', '5:6', '8', '10' ];
And, for the sake of TIMTOWTDI:
my @input = (1, 2, 3, 5, 6, 8, 10);
my $last = $input[0];
my @ranges = map {
($_ > $#input || $input[$_] != 1 + $input[ $_ - 1 ])
? do {
my $s = $last . (":$input[ $_ - 1 ]") x ($last != $input[
+$_ - 1 ]);
$last = $input[$_];
$s
}
: ();
} 1 .. $#input + 1;
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
| [reply] [d/l] [select] |
Re: Generating ranges of numbers
by Anonymous Monk on Jun 30, 2016 at 13:43 UTC
|
#!/usr/bin/perl -l
# http://perlmonks.org/?node_id=1166921
use strict;
use warnings;
my @array = ("1","2","3","5","6","7","9");
my @ranges = split ' ', "@array"
=~ s/\b(\d+)\K (?=(\d+)(??{$1 != $2 - 1 && 'fail' }))/:/gr
=~ s/:[\d:]+:/:/gr;
print "@ranges";
| [reply] [d/l] |
Re: Generating ranges of numbers
by hdb (Monsignor) on Jul 01, 2016 at 08:06 UTC
|
use warnings;
use strict;
my @input = (-1, 1, 2, 3, 5, 6, 8, 10, 11, 12, 13 );
my @ranges = ( [ $input[0] ] );
for (@input[1..$#input]) {
if( $_ == $ranges[-1][-1]+1 ) {
$ranges[-1][1] = $_;
} else {
push @ranges, [ $_ ];
}
}
$" = ":";
print "@$_\n" for @ranges;
Update: replaced "eq" with "==" above. | [reply] [d/l] |
Re: Generating ranges of numbers
by Marshall (Canon) on Jun 30, 2016 at 15:49 UTC
|
Also in the interest of TIMTOWTDI. A bit more wordy than other solutions, but straightforward...
#!usr/bin/perl
use strict;
use warnings;
my @array = ("1","2","3","5","6","7","9");
my @working = @array; #copy to "consume"
my $start = shift @working;
my $current= $start;
my @output;
while (my $next = shift @working)
{
if ($next == $current+1)
{
$current = $next;
}
else
{
got_result();
$start = $current = $next;
}
}
got_result();
print join ",",@output; #prints: 1:3,5:7,9
sub got_result
{
if ($start == $current )
{
push @output, "$start";
}
else
{
push @output, "$start:$current";
}
}
| [reply] [d/l] |
Re: Generating ranges of numbers
by Anonymous Monk on Jun 30, 2016 at 14:10 UTC
|
#!/usr/bin/perl -l
# http://perlmonks.org/?node_id=1166921
use strict;
use warnings;
my @array = ("1","2","3","5","6","7","9");
my @ranges = "@array" =~
s/\b(\d+)\K (?=(\d+)(??{$1 != $2 - 1 && 'fail' }))/:/gr =~
s/:\S+:/:/gr =~
/\S+/g;
print "@ranges";
| [reply] [d/l] |
Re: Generating ranges of numbers
by Anonymous Monk on Jun 30, 2016 at 17:43 UTC
|
#!/usr/bin/perl -l
# http://perlmonks.org/?node_id=1166921
use strict;
use warnings;
my @array = ("1","2","3","5","6","7","9");
my @ranges = "@array" =~
s/\b(\d+)(?{$1})\K(?: (\d+)\b(??{++$^R!=$2}))+/:$2/gr =~ /\S+/g;
print "@ranges";
| [reply] [d/l] |
|
|