Re: How can I reduce this with a REGEX?
by pvaldes (Chaplain) on Mar 14, 2014 at 15:50 UTC
|
use List::MoreUtils qw{uniq}
while (<FH>){
chomp;
convert each line to an array of numbers splitting by "-"
sort the resulting list of numbers
and apply uniq to this list: my @list_of_unique_items = uniq @list;
join or print again each element followed by a "-"
chomp again if needed to delete the last "-"
undef the array
process the next line
| [reply] [d/l] |
|
|
..appreciate it guys but I'm trying to make this solution simpler & shorter- not longer!
This isn't too bad I spose.. Seems to work in a 1-liner:
s/(\d\d)((-\d\d)*?)(-\1)/$1$2/g while /(\d\d).*(-\1)/;
| [reply] |
|
|
Which can probably be further reduced to:
$ cat 1078350.in
12-12
12-12-12
12-13-12-13
12-12-13-13
12-13-13-14
$ perl -pe '1 while s/(\d\d)(.*?)(?:-\1)/$1$2/g' 1078350.in
12
12
12-13
12-13
12-13-14
| [reply] [d/l] |
|
|
Re: How can I reduce this with a REGEX?
by hdb (Monsignor) on Mar 14, 2014 at 17:48 UTC
|
use strict;
use warnings;
my @strings = qw( 12-12 12-12-12 12-13-12-13 12-12-13-13 12-13-13-14 )
+;
for (@strings) {
my %hash;
s/(\-?)(\d\d)/ $hash{$2}++ ? '' : $1.$2 /ge;
print "$_\n";
}
| [reply] [d/l] |
Re: How can I reduce this with a REGEX?
by johngg (Canon) on Mar 14, 2014 at 23:38 UTC
|
$ perl -Mstrict -Mwarnings -E '
say join q{-}, do {
my %seen;
grep { not $seen{ $_ } ++ } split m{-};
} for qw{
12-12
12-12-12
12-13-12-13
12-12-13-13
12-13-13-14
};'
12
12
12-13
12-13
12-13-14
$
I hope this is helpful.
| [reply] [d/l] |
Re: How can I reduce this with a REGEX?
by Laurent_R (Canon) on Mar 14, 2014 at 22:40 UTC
|
Or using a data pipeline with sort and grep:
use strict;
use warnings;
my @strings = qw( 12-12 12-12-12 12-13-12-13 12-12-13-13 12-13-13-14 )
+;
for (@strings) {
my $prev = -1; # numbers being separated by dashes, I assume that
+a negative value is not possible
print join "-", grep {$prev != $_ and $prev = $_} sort {$a <=> $b}
+ split /-/, $_;
print "\n";
}
which prints:
12
12
12-13
12-13
12-13-14
| [reply] [d/l] [select] |
Re: How can I reduce this with a REGEX?
by Lennotoecom (Pilgrim) on Mar 14, 2014 at 16:46 UTC
|
maybe you'll consider hashes?
while(<DATA>){
%h = ();
undef $h{$1} while(s/(\d\d)//);
print join ("-", sort keys %h),"\n";
}
__DATA__
12-12
12-12-12
12-13-12-13
12-12-13-13
12-13-13-14
updated $h{$1} = null became undef $h{$1}
thank you Mr. choroba | [reply] [d/l] |
|
|
I would also use matching instead of substitution. You mentioned in a private message that the substitution is faster (using such a trick would be worth a comment), but my benchmark doesn't show the effect. To speed things up, rather use my %h instead of %h = ().
Output:
Rate lenno choro
lenno 25358/s -- -4%
choro 26458/s 4% --
Perl 5.16.2, x86_64-linux-thread-multi.
Update:
Significantly faster: use a hash slice undef @h{m/\d\d/g}; instead of the inner loop.
| [reply] [d/l] [select] |
|
|
Yes, thank you for your reply, I apparently got mistaken,
I'm deeply sorry. You were right.
My results:
use Benchmark(cmpthese);
cmpthese(1000000, {
'a' => sub {
$_ = '12-12-12-12-12';
undef $h{$1} while (s/(\d\d)//);
},
'b' => sub {
$_ = '12-12-12-12-12';
undef $h{$1} while (m/(\d\d)/g);
},
'c' => sub {
$_ = '12-12-12-12-12';
undef @h{m/\d\d/g};
}
});
results:
Rate a b c
a 195427/s -- -19% -35%
b 241896/s 24% -- -20%
c 300933/s 54% 24% --
| [reply] [d/l] [select] |
Re: How can I reduce this with a REGEX?
by Anonymous Monk on Mar 14, 2014 at 15:44 UTC
|
still working on it- found a mistake.. this seems to work:
while ( /(\d\d).*(-\1)/ ) {
s/(\d\d)((-\d\d)*?)(-\1)/$1$2/g;
}
but I still arent in love with having to use the while ()
| [reply] |