On Wed, Nov 10, 1999 at 01:19:29PM -0600, Bennett Todd wrote: > 1999-11-10-13:30:18 tomr@aceldama.com: > > > > @cats = @cats[map (($_/2 + ($_ % 2) * $#cats/2), 0..$#cats)]; > > > > [...] Anyone else have comments? > > You are a sick little monkey. I like that. :-) > > Seriously, this is something I frequently need to do, and I've never > seen such > a lovely way of saying it. Next natural question would be, does it keep > working for ncols!=2. Looks to me like it does. Are you sure? It tried a simple case (1..9) and it didn't. 5 was repeated and 9 was lost. The following adjustment took care of it, though: @cats = @cats[map (($_/2 + ($_ % 2) * ($#cats/2 + 1)), 0..$#cats)]; ^ ^^^^^ Oddly, benchmarking indicates that Tom's way is about twice as fast as mine, which was: my $half = $#cats/2; @cats = @cats[map (($_, $_+$half+1), 0..$half)]; Knowing next to nothing about Perl internals, I'm guessing that it's something to do with growing the list at each iteration of the map. Implementing the optimization Tom mentioned: my $half = $#cats/2; @cats = @cats[map (($_/2 + ($_ % 2) * ($half + 1)), 0..$#cats)]; results in a pretty substantial speedup (almost 25%). Here are the numbers, in case anyone is interested: Benchmark: timing 100 iterations of Mine, Tom's, Tom's improved... Mine: 44 wallclock secs (41.43 usr + 0.04 sys = 41.47 CPU) Tom's: 24 wallclock secs (22.20 usr + 0.00 sys = 22.20 CPU) Tom's improved: 17 wallclock secs (16.93 usr + 0.00 sys = 16.93 CPU) And here's the code: #!/usr/local/bin/perl -w use strict; use Benchmark; my @array = (0..8000); sub mine { my $half = $#array/2; map (($_, $_+$half+1), 0..$half); } sub toms { map (($_/2 + ($_ % 2) * ($#array/2 + 1)), 0..$#array); } sub toms_opt { my $half = $#array/2; map (($_/2 + ($_ % 2) * ($half + 1)), 0..$#array); } timethese(100, {"Mine" => \&mine, "Tom's" => \&toms, "Tom's improved" => \&toms_opt}); ==== Want to unsubscribe from Fun With Perl? Well, if you insist... ==== Send email to <fwp-request@technofile.org> with message _body_ ==== unsubscribe