Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Which module formats runs of integers a la 1, 4-7, 8, 10?
=00


Report this thread to moderator Post Follow-up to this message
Old Post
Ron Savage
04-09-05 08:56 AM


Re: Which module formats runs of integers a la 1, 4-7, 8, 10?
Ron Savage wrote:
> Which module formats runs of integers a la 1, 4-7, 8, 10?

Not sure - does it warrant a module?  Also, I presume that the list
output should be 1,4-8,10 rather than listing 4-7 and 8 separately.

I have a piece of code which can readily be adapted to the job.  The
original use is for formatting up the list of years when changes were
made (to a source file kept in RCS), suitable for use in a copyright
message.

#!/bin/perl -w

use strict;
my @values;

# Generate a list of numbers, discarding all non-digits
while (<> )
{
chomp;
next unless /\d/;
my(@nums) = split /\D+/, $_;
push @values, @nums;
}

# Sort the list numerically.
@values = sort { $a <=> $b } @values;

# Generate a list such as 1,4-8,10
my ($list, $old) = ("", shift @values);
foreach my $value (@values)
{
my $pad = ($value == $old+1) ? "-" : ",";
$list =~ s/-$old$// if ($value == $old+1);
$list .= "$pad$value";
$old = $value;
}
$list =~ s%^,%%;    # Remove leading comma

print $list;

Have fun.

--
Jonathan Leffler                   #include <disclaimer.h>
Email: jleffler@earthlink.net, jleffler@us.ibm.com
Guardian of DBD::Informix v2005.01 -- http://dbi.perl.org/

Report this thread to moderator Post Follow-up to this message
Old Post
Jonathan Leffler
04-09-05 08:56 AM


Re: Which module formats runs of integers a la 1, 4-7, 8, 10?
Jonathan Leffler wrote:
> Ron Savage wrote: 
>
> Not sure - does it warrant a module?  Also, I presume that the list
> output should be 1,4-8,10 rather than listing 4-7 and 8 separately.
>
> I have a piece of code which can readily be adapted to the job.  The
> original use is for formatting up the list of years when changes were
> made (to a source file kept in RCS), suitable for use in a copyright
> message.

Darn it - this doesn't handle empty lists or lists of one number properly.

> #!/bin/perl -w
>
> use strict;
> my @values;
>
> # Generate a list of numbers, discarding all non-digits
> while (<> )
> {
>     chomp;
>     next unless /\d/;
>     my(@nums) = split /\D+/, $_;
>     push @values, @nums;
> }

exit 0 if $#values < 0;

> # Sort the list numerically.
> @values = sort { $a <=> $b } @values;
>
> # Generate a list such as 1,4-8,10
> my ($list, $old) = ("", shift @values);

# Replace the above with...

my($old) = shift @values;
my($list) = "$old";

> foreach my $value (@values)
> {
>     my $pad = ($value == $old+1) ? "-" : ",";
>     $list =~ s/-$old$// if ($value == $old+1);
>     $list .= "$pad$value";
>     $old = $value;
> }
> $list =~ s%^,%%;    # Remove leading comma
>
> print $list;
>
> Have fun.
>


--
Jonathan Leffler                   #include <disclaimer.h>
Email: jleffler@earthlink.net, jleffler@us.ibm.com
Guardian of DBD::Informix v2005.01 -- http://dbi.perl.org/

Report this thread to moderator Post Follow-up to this message
Old Post
Jonathan Leffler
04-09-05 08:56 AM


Re: Which module formats runs of integers a la 1, 4-7, 8, 10?
Jonathan Leffler wrote (correcting himself the first time):
> Jonathan Leffler wrote: 
>
> Darn it - this doesn't handle empty lists or lists of one number properly.

Double bother.  The original code used a hash to eliminate duplicates; I
didn't test the revised code on lists with duplicates.  The embarassment.

This version has been tested on an empty file, on a file with a single
number, a file with no numbers, on itself, and on a pile of junk.  On
itself, it produces the output: 0-2,4-10,50,2005

#!/bin/perl -w
#
# @(#)$Id: printlist.pl,v 1.2 2005/04/09 06:06:58 jleffler Exp $
#
# Convert numbers into appropriately grouped lists
# Eg: 1,4a6kk5x7x8,10 becomes 1,4-8,10

use strict;
my %values;

# Read values, ignoring non-digits except as number delimiters.
# Use hash to eliminate duplicates.
while (<> )
{
chomp;
foreach my $num (split /\D+/, $_)
{
next unless $num =~ /\d/;
$num =~ s/^0+(\d)/$1/o;
$values{$num} = 1;
}
}

# Convert to numerically sorted list
my @values = sort { $a <=> $b } keys %values;

# Exit if list is empty
exit 0 if $#values < 0;

# Format result
my ($old) = shift @values;
my ($list) = "$old";
foreach my $value (@values)
{
my $pad = ($value == $old+1) ? "-" : ",";
$list =~ s/-$old$// if ($value == $old+1);
$list .= "$pad$value";
$old = $value;
}
$list =~ s%^,%%;    # Remove leading comma

print "$list\n";

The 'next unless' test in the reader loop eliminates empty strings.  The
split expression eliminates other non-digits.  It probably isn't optimal
but it does seem to work.

--
Jonathan Leffler                   #include <disclaimer.h>
Email: jleffler@earthlink.net, jleffler@us.ibm.com
Guardian of DBD::Informix v2005.01 -- http://dbi.perl.org/

Report this thread to moderator Post Follow-up to this message
Old Post
Jonathan Leffler
04-09-05 08:56 AM


Re: Which module formats runs of integers a la 1, 4-7, 8, 10?
Set::IntSpan

--
Peter Scott
http://www.perlmedic.com/
http://www.perldebugged.com/


Report this thread to moderator Post Follow-up to this message
Old Post
Peter Scott
04-09-05 01:56 PM


Re: Which module formats runs of integers a la 1, 4-7, 8, 10?
On Sat, 9 Apr 2005 21:01:28 +1000, Peter Scott wrote:

Hi Jonathan and Peter

Thanx for the replies.

I will have a play with Jonathan's code.

As for Set::IntSpan, I did read up on it before posting, but not carefully
enough. For some reason I thought it was not appropriate.
Sorry - I should have mentioned that up front.




Report this thread to moderator Post Follow-up to this message
Old Post
Ron Savage
04-10-05 08:55 AM


Re: Which module formats runs of integers a la 1, 4-7, 8, 10?
On Sat, 9 Apr 2005 21:01:28 +1000, Peter Scott wrote:

Hi Folks

Ahh, I see now. I had been reading up on Set::IntRange, and had not gotten=
to
Set::IntSpan :-(.




Report this thread to moderator Post Follow-up to this message
Old Post
Ron Savage
04-10-05 08:55 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

PERL Modules archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 07:06 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.