in reply to Create union from ranges, but compare respectively
perl -le "for($ARGV[0]=~/\-/g){my@a;map{$a[$_]++for(eval s/\-/\.\./r)} +map{s/^([^,]*),?//;$1}@ARGV;print+(join'-',(grep$a[$_]==2,0..$#a)[0,- +1])}" "25-40,74-93,95-120,130-149" "31-47,84-99,107-123,137-151" 31-40 84-93 107-120 137-149
L*
PS this should be the sub to add to the above bench ( UPDATE it had many errors: corrected)
sub _oneliner{ my @res; for($TM_part1=~/\-/g) { my @arr; # map{ $arr[$_]++ for (eval s/\-/\.\./r) } map{ s/^([^,]*) +,?//; $1 }$TM_part1, $TM_part2; # semplified a bit, see below map{s/^([^,]*),?//;$arr[$_]++ for( eval $1 =~ s/\-/\.\./r +)}$TM_part1,$TM_part2; push @res,(join'-',(grep { defined $arr[$_] and $arr[$_] = += 2 }0..$#arr)[0,-1] ); } return join ',', @res; } __END__ 1..4 ok 1 ok 2 ok 3 ok 4 Rate Span Perl Pair Oneliner Span 12055/s -- -27% -84% -100% Perl 16553/s 37% -- -79% -100% Pair 77602/s 544% 369% -- -99% Oneliner 11429533/s 94715% 68949% 14628% --
UPDATE the double map is really redundant and unneeded in the above sub:
# map{$arr[$_]++ for(eval s/\-/\.\./r)}map{s/^([^,]*),?//;$1}$TM_part1 +,$TM_part2; # should be: map{s/^([^,]*),?//;$arr[$_]++ for( eval $1 =~ s/\-/\.\./r )}$TM_part1, +$TM_part2; # so also the oneliner can be reduced: perl -le "for($ARGV[0]=~/\-/g){my@a;map{s/^([^,]*),?//;$a[$_]++for eva +l$1=~s/\-/\.\./r}@ARGV;print join'-',(grep$a[$_]==2,0..$#a)[0,-1]}" "25-40,74-93,95-120,130-149" "31-47,84-99,107-123,137-151" 31-40 84-93 107-120 137-149
PS I fixed 1..$#a with 0..$#a in the above code snippets
|
|---|