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.

In reply to Re: Re: interleave (single shuffle) by ysth
in thread interleave (single shuffle) by ysth

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.