Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Reading next line, finding missing number in sequence

Reply
Thread Tools

Reading next line, finding missing number in sequence

 
 
Pea
Guest
Posts: n/a
 
      08-10-2004
Hello,
I know this has been discussed before and I've tried some of the
solutions too. But I've been unsuccessful so far. I have a simple
text file of numbers, one on each line and just need a script that
will find the missing number. Example of file:
1
2
3
5

My script:

open (FILE, "FILE.txt");
open (MISSING, ">Missing.txt");

while (<FILE>) {
$currline = $_;
$nxtline=$currline++ ;
if ($_ != $nxtline) {
print MISSING "Missing occurrence is $_ \n";
}
}

close FILE;
close MISSING;

This doesn't identify that 4 is missing. Any ideas?
Thank you in advance,
Tara Pillion
 
Reply With Quote
 
 
 
 
Matt Garrish
Guest
Posts: n/a
 
      08-10-2004

"Pea" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hello,
> I know this has been discussed before and I've tried some of the
> solutions too. But I've been unsuccessful so far. I have a simple
> text file of numbers, one on each line and just need a script that
> will find the missing number. Example of file:
> 1
> 2
> 3
> 5
>
> My script:
>


Where are strictures and warnings?

use strict;
use warnings;

> open (FILE, "FILE.txt");


Always check that your file even gets opened:

open(my $infile, '<', 'FILE.txt') or die "Could not open the input file:
$!";

> open (MISSING, ">Missing.txt");
>


Once again:

open(my $outfile, '>', 'Missing.txt') or die "Could not open the output
file: $!";

> while (<FILE>) {
> $currline = $_;
> $nxtline=$currline++ ;
> if ($_ != $nxtline) {
> print MISSING "Missing occurrence is $_ \n";
> }
> }
>


In the above, you assign the value of the line to $currline, then add 1 and
assign it to $nxtline. You then test whether the value on the input line
equals the number you just incremented? This should fail for *all* cases
(i.e., 1+1 != 1, 2+1 != 2, etc.).:

my $cnt = 1;

while (my $num = <$infile>) {

if ($num != $cnt) {

print $outfile "Missing number(s): ";

for (($num - ($num - $cnt)) .. ($num - 1)) {
print $outfile "$_,";
}

print $outfile " at line $.\n";

$cnt = $num;
}

$cnt++;
}


Matt


 
Reply With Quote
 
 
 
 
Matt Garrish
Guest
Posts: n/a
 
      08-11-2004

"Matt Garrish" <(E-Mail Removed)> wrote in message
news:h7dSc.20263$(E-Mail Removed). ..
>
>
> for (($num - ($num - $cnt)) .. ($num - 1)) {
>


That, of course, would be the long way of writing:

for ($cnt .. ($num -1)) {

I was trying something else and never looked twice at it when I switched
gears... : )

Matt


 
Reply With Quote
 
Tad McClellan
Guest
Posts: n/a
 
      08-11-2004
Pea <(E-Mail Removed)> wrote:

> text file of numbers, one on each line and just need a script that
> will find the missing number.



> open (FILE, "FILE.txt");



You should always, yes *always*, test the return value from open():

open (FILE, 'FILE.txt') or die "coult not open 'FILE.txt' $!";


> Any ideas?



Does it have to work when there is more than one number in a row omitted?

If not, then:

---------------------------------------
#!/usr/bin/perl
use warnings;
use strict;

for ( my $prev=<DATA>; my $num = <DATA>; $prev = $num) {
print $prev+1, " is missing\n" if $num != $prev+1;
}


__DATA__
1
2
3
5
---------------------------------------


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
Andrew Palmer
Guest
Posts: n/a
 
      08-11-2004
"Brian Kell" <(E-Mail Removed)> wrote in message
newspscjh0fq0z772u5@pc0938...
> On Tue, 10 Aug 2004 16:14:50 -0700, Jim Gibson <(E-Mail Removed)>
> wrote:
>
> > my $expected = 1;
> > while(<FILE>) {
> > if( $_ != $expected ) {
> > print MISSING "Missing ...";
> > }
> > $expected = $_ + 1;
> > }

>
> But consider this file:
>
> 1
> 2
> 3
> 5
> 6
> 7
> 9
> 10
>
> This script will print:
>
> Missing 4...
> Missing 5...
> Missing 6...
> Missing 7...
> Missing 8...
>


Hmm... I get only:

Missing 4
Missing 8

which is correct, isn't it?


> (Assuming, of course, that you modified it to print the missing number.)


I modified it thus:

my $expected = 1;
while(<DATA>) {
if( $_ != $expected ) {
print "Missing $expected\n";
}
$expected = $_ + 1;
}

__DATA__
1
2
3
5
6
7
9
10



>
> Brian
>
> -----
>
>

($a='%Q$yW0se3%qhggfIi')=~s,([f-y]),qq;"\\c$1";,ege,@l=unpack'a5a5a*',$a;for
$i(
> @l){$$i.=sprintf"%lx",$_ for
> unpack'C*',$i;push@n,$$i;}$"=',',$_="\c`",$p=eval"
>

pack'VVN',@n",@b=unpack'C12',$p;$m=4054314,$a=96;( ++$a,$m>>=1)&1?s@$@chr$a-!
($a
> %6-4)*32@e:$;while$m;@z=split m
> &&;for$j(@b){print$z[$j&15|($j>>=4,0)]for+z,j;}




 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      08-11-2004
Pea <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Hello,
> I know this has been discussed before and I've tried some of the
> solutions too. But I've been unsuccessful so far. I have a simple
> text file of numbers, one on each line and just need a script that
> will find the missing number. Example of file:
> 1
> 2
> 3
> 5
>
> My script:
>
> open (FILE, "FILE.txt");
> open (MISSING, ">Missing.txt");
>
> while (<FILE>) {
> $currline = $_;
> $nxtline=$currline++ ;
> if ($_ != $nxtline) {
> print MISSING "Missing occurrence is $_ \n";
> }
> }
>
> close FILE;
> close MISSING;


my @data = <FILE>;
my @missing = 0 .. $data[ -1];
@missing[ @data] = ();
print "@{[ grep defined, @missing]}\n";

That reports 0 as missing too, but that's easy to correct. A variant
delivers the missing elements without intervening undef's:

my @data = <FILE>;
my @missing = 0 .. $data[ -1];
splice @missing, $_, 1 for reverse @data;
print "@missing\n";

Anno
 
Reply With Quote
 
Pea
Guest
Posts: n/a
 
      08-11-2004
Thank you, Brian. I used your suggestion and modification and it
worked well, except when there were two numbers in a row missing. For
example, if I had
1
2
5
6
7

It would list 3 as the missing number but not 4. I can work with this
though. Thanks a bunch.

Tara

> "Brian Kell" <(E-Mail Removed)> wrote in message
> newspscjh0fq0z772u5@pc0938...
> > I modified it thus:

>
> my $expected = 1;
> while(<DATA>) {
> if( $_ != $expected ) {
> print "Missing $expected\n";
> }
> $expected = $_ + 1;
> }
>
> __DATA__
> 1
> 2
> 3
> 5
> 6
> 7
> 9
> 10
>
> > Brian

 
Reply With Quote
 
Andrew Palmer
Guest
Posts: n/a
 
      08-11-2004

"Pea" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Thank you, Brian. I used your suggestion and modification and it
> worked well, except when there were two numbers in a row missing. For
> example, if I had
> 1
> 2
> 5
> 6
> 7
>
> It would list 3 as the missing number but not 4. I can work with this
> though. Thanks a bunch.
>
> Tara
>
> > "Brian Kell" <(E-Mail Removed)> wrote in message
> > newspscjh0fq0z772u5@pc0938...
> > > I modified it thus:

> >
> > my $expected = 1;
> > while(<DATA>) {
> > if( $_ != $expected ) {
> > print "Missing $expected\n";
> > }
> > $expected = $_ + 1;
> > }


Here's an idea

my $expected = 1;
while(<DATA>) {
for(;$expected < $_;++$expected) {
print "Missing $expected\n";
}
$expected=$_+1;
}

Some of the other solutions posted here, handle this scenario as well,
though.

> >
> > __DATA__
> > 1
> > 2
> > 3
> > 5
> > 6
> > 7
> > 9
> > 10
> >
> > > Brian




 
Reply With Quote
 
Joe Smith
Guest
Posts: n/a
 
      08-11-2004
>>(Assuming, of course, that you modified it to print the missing number.)

I would expect to print out all the missing numbers when the increase
is more than two. Why limit it to always start at 1?

linux% cat count.pl
#!/usr/bin/perl

my $expected;
while(<DATA>) {
if (defined $expected) {
die "Bad data: expected=$expected, read=$_" if $_ < $expected;
print "Missing ",$expected++,"\n" while $expected < $_;
}
$expected = $_ + 1;
}

__DATA__
2
3
5
9
10
linux% perl count.pl
Missing 4
Missing 6
Missing 7
Missing 8

-Joe
 
Reply With Quote
 
Matt Garrish
Guest
Posts: n/a
 
      08-11-2004

"Brian Kell" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
> On Tue, 10 Aug 2004 19:46:26 -0400, Matt Garrish
> <(E-Mail Removed)> wrote:
>
> >> while (<FILE>) {
> >> $currline = $_;
> >> $nxtline=$currline++ ;
> >> if ($_ != $nxtline) {
> >> print MISSING "Missing occurrence is $_ \n";
> >> }
> >> }
> >>

> >
> > In the above, you assign the value of the line to $currline, then add 1
> > and
> > assign it to $nxtline. You then test whether the value on the input line
> > equals the number you just incremented? This should fail for *all* cases
> > (i.e., 1+1 != 1, 2+1 != 2, etc.).:

>
> Not quite; $nxtline will get the value of $currline before the increment.
> So it will *succeed* for all cases.
>


First Dr. Seuss and now this. I need a vacation...

Matt


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to iterate over sequence and non-sequence ? stef mientki Python 13 10-20-2007 10:21 AM
Reading of file by next of map file and by next of file descriptor. =?ISO-8859-2?Q?Miros=B3aw?= Makowiecki C++ 1 07-10-2007 02:46 AM
Finding the next file in a sequence Niall Macpherson Perl Misc 7 01-17-2006 01:39 PM
CurrentElement->next = CurrentElement->next->next (UNDEFINED?) Deniz Bahar C Programming 2 03-09-2005 12:45 AM
BOOT SEQUENCE (how to change boot sequence) bird Computer Support 13 12-24-2003 02:20 AM



Advertisments