in reply to Re: interleave (single shuffle)
in thread interleave (single shuffle)
Nice, but why the bit ops? This isn't assembler. sub interleave { @_[ map $_ % 2 ? $_ / 2 : ( $_ / 2 ) + ( $#_ / 2 ), 1 .. @_ ] }Perl is not assembler, only assembler code uses bit ops, ergo perl code never uses bit ops? There are as many valid subsets of Perl as there are Perl programmers, and then some. Every programmer should use the parts with which he/she is familiar, with due allowance for whatever audience, coworkers, etc. exist. Here at perlmonks, I'm only likely to veer from my "native dialect" when answering a newbie's question.
To more directly address your question, this is an integer transformation problem and bit ops are part of my mental toolbox for that kind of problem. It didn't even occur to me to use /2 instead. Note that my code produces indices 0,5,1,6,2,7,3,8,4,9 for a list of 10, while your first version produces 0.5,5.5,1.5,6.5,2.5,7.5,3.5,8.5,4.5,9.5. They are equivalent, since array subscripts are converted to int, and your version is just as good as mine, but I was thinking only of integer operations and your thinking was more unbounded.
Now there are several things that irk me. One is the duplication of $_ / 2. The other is 1 .. @_ which surprised me for 1/10th of a second. sub interleave { @_[ map $_ / 2 + ( $_ % 2 ? $#_ / 2 : 0 ), 0 .. $#_ ] }I agree that 0 .. $#_ may be a little clearer. (Side thought: how about @_[ sort { ... } 0..$#_ ].) But you've introduced an error when there are an odd number of parameters. Try @_/2 instead. Also see Bart's version where he has a&&b instead of a?b:0.
IMHO it's much easier to see what's going on. But I'd write it differently: sub interleave { @_[ map +( $_, $_ + @_ / 2 ), 0 .. $#_ / 2 ] } That gets us rid of the constant evaluation of a condition and reduces the number of iterations by half. You might want to move the @_ / 2 invariant out of the loop as a final optimization. The inner loop is now extremly simple: two additions. This is faster than your cryptic bit ops version and still clear as day to read. Don't microoptimize, pick a good algorithm first. You'll always get more readable as well as faster code.Thanks, that is a fair amount faster. But again, I wasn't actually trying to optimize, and your last example only works for an even number of parameters.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: interleave (single shuffle)
by Aristotle (Chancellor) on Nov 27, 2003 at 04:05 UTC |