Re: find the continuity in the data file
by repellent (Priest) on Feb 05, 2012 at 02:50 UTC
|
my @n = qw(16 107 108 110 112 114 115 117 118 119 120 121 122 123 124
+125 127 128 130 132 133 135 136 138 142 146 149 150 154 156 157 158 1
+59 161 162);
my $set = Set::IntSpan::Fast->new;
$set->add(@n);
print $set->as_string, "\n";
__END__
16,107-108,110,112,114-115,117-125,127-128,130,132-133,135-136,138,142
+,146,149-150,154,156-159,161-162
| [reply] [d/l] [select] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: find the continuity in the data file
by Anonymous Monk on Feb 04, 2012 at 15:33 UTC
|
How would you do it using paper and pencil, without a computer? Please post your answer
| [reply] |
Re: find the continuity in the data file
by oko1 (Deacon) on Feb 04, 2012 at 22:29 UTC
|
#!/usr/bin/perl -w
use strict;
my @nums=qw(16 107 108 110 112 114 115 117 118 119 120 121 122 123 124
+ 125 127 128 130 132 133 135 136 138 142 146 149 150 154 156 157 158
+159 161 162);
my $limit = 4;
my ($prev, $top) = shift @nums;
for (@nums){
if ($prev + 1 == $_){
if (++$top == $limit){
die "Sequence of $limit found between @{[$_-$limit]} and $
+_\n";
}
}
else {
$top = 0;
}
$prev = $_;
}
--
Education is not the filling of a pail, but the lighting of a fire.
-- W. B. Yeats
| [reply] [d/l] |
Re: find the continuity in the data file
by chessgui (Scribe) on Feb 04, 2012 at 16:26 UTC
|
my @nums=qw(16 107 108 110 112 114 115 117 118 119 120 121 122 123 124
+ 125 127 128 130 132 133 135 136 138 142 146 149 150 154 156 157 158
+159 161 162);
my $limit=4;
my $direction=1;
my @cont=get_cont($limit,$direction,@nums);
if(@cont>0)
{
print "First continuous block of $limit numbers in ",$direction>0?
+"ascending":"descending"," direction is: ",join(',',@cont);
}
else
{
print "No block was found.\n";
}
sub get_cont
{
my $limit=shift;
my $dir=shift;
my @nums=@_;
my $prev;
my @cont;
for $num (@nums)
{
if(($num-$prev)==$dir)
{
push(@cont,$num);
if(@cont>=$limit)
{
return @cont;
}
}
else
{
@cont=();
}
$prev=$num;
}
return ();
}
Change $limit to 2500 for your real data (and direction to -1 if you want continuous blocks of descending numbers). | [reply] [d/l] |
Re: find the continuity in the data file
by TJPride (Pilgrim) on Feb 05, 2012 at 07:46 UTC
|
This isn't particularly difficult from an algorithm perspective, but you've made the rookie mistake of giving us no examples of what you want for input settings or output data and then expecting us to magically divine the answer. I'm just going to +1 the decent answers here and move on. | [reply] |
|
#!/usr/bin/perl -w
use strict;
use warnings;
# program identifies if the number series contains > 2500 continuo
+us numbers
# read this number series into a arr1
# if (length < 2500)
# then ,discrad
# else {
# for (i=1 to $len)
# idenitfy the indices where there are breaks and
# store these indices into arr2
# foreach element in this @arr2
# if the difference in the indices > 2500
# then take the diff and print the range
use Data::Dumper;
my @files = </Users/distance/8A/*>;
foreach my $file (@files){
my $file = $ARGV[0];
open INFILE," $file" or die "$!\n";
<INFILE>;
<INFILE>;
my @arr1 = <INFILE>;
close INFILE;
my $len = scalar(@arr1) ;
print "$len\n" ;
my (@range, %h, @numbers);
if ($len < 2500) {
print "no use of searching\n" ;
}
else {
my $last_line = $#arr1;
my ($range_start, $range_end) = ('', '');
for (my $i = $last_line; $i > 0; $i--)
{
my $line = $arr1[$i];
if ($line =~ /t:\s*(\d+)/)
{
push(@numbers, $1);
}
}
}
if (scalar @numbers){
for (my $i = 0; $i< scalar(@numbers); $i++){
last if ($i+1 > $#numbers);
my $f = $numbers[$i];
my $s = $numbers[$i+1];
if ($f - $s == 1)
{
$h{s} = $f if (!$h{s});
$h{e} = $s;
}else{
push(@range, [[$h{e}, $h{s}]]);
$h{s} = 0;
$h{e} = 0;
# can be updated to any number to get all the ranges
# for now gives only two ranges
last if (scalar @range == 2);
}
}
}
# in case its only one range
if ($h{s} && $h{e} && !scalar(@range))
{
push (@range, [$h{e}, $h{s}]);
}
print Dumper \@range;
}
i get an error as= Use of uninitialized value $file in concatenation (.) or string at test.pl line 31 | [reply] [d/l] |
|
"Use of uninitialized value" is a warning, not an error. Line 31 of your posted program is
close INFILE;
so you are probably running a different version of the code.
Another suspicious thing is your open: do you really prepend a space to the argument? | [reply] [d/l] [select] |
|
<INFILE>;
<INFILE>;
my @arr1 = <INFILE>;
close INFILE;
| [reply] [d/l] |
|
From the context, I'm assuming your files have two header lines and then one number per line.
use strict;
use warnings;
for (rangeOver(*DATA, 4)) {
print "$_->[0] to $_->[1] = " .
($_->[1] - $_->[0] + 1) . "\n";
}
sub rangeOver {
my ($fh, $min) = @_;
my ($start, $end, @ranges, $i);
<$fh>; <$fh>;
chomp(@_ = <$fh>);
return [] if $#_ < $min - 1;
$start = $end = shift;
for (@_) {
if ($_ == $end + 1) {
$end++; next;
}
push @ranges, [$start, $end]
if $end >= $start + $min - 1;
$start = $end = $_;
}
push @ranges, [$start, $end]
if $end >= $start + $min - 1;
return @ranges;
}
__DATA__
some
header
1
3
4
5
6
8
10
11
12
13
14
| [reply] [d/l] |
Re: find the continuity in the data file
by DrHyde (Prior) on Feb 06, 2012 at 10:12 UTC
|
What have you tried so far, and how do the results differ from what you want and from what you expect? | [reply] |