I tried the idea of converting the args into a 2D array of 0/1s with unpack, then inverting it. That way you can perform the swapping of bits on all the rows in one go (swapping anonymous arrays around). You then reinvert and pack back to ints before finally sorting and returning.

It works, but it's certainly not quicker.

I also built a lookup table for the specific case. 3-bits gives an table with 7 elements (x-column value if 0..6. 7 is impossible because it leaves no place for the 'x'). Each of the 7 first level elements has the potential for 3 sets of swaps (one for each combination of x-column value * position of the x).

Of the 21 possible combinations, 9 are impossible and 2 require no swaps (they are correctly ordered on input). For each of the 10 remaining you need either 1 or 2 pairs of column indexes that require swapping, that need to be applied to each of the args.

## 3-bit case only. my %reorder = ( 0 => [ undef , [[0,1]], [[0,1],[1,2]] ], 1 => [ undef , [[0,1]], [[0,2]] ], 2 => [ [[0,1]] , undef , [[0,1],[1,2]] ], 3 => [ undef , undef , undef ], 4 => [ [[1,2],[0,1]], [[0,2]], [] ], 5 => [ undef , [[1,2]], undef ], 6 => [ [[0,1],[1,2]], undef , undef ], ); sub reorder { my( $dim, $height, $v, $args ) = @_; my $xforms = $reorder{ $args->[ $v ] }[ $height ]; return $args unless $xforms; for my $arg ( @$args ) { swapBits( $arg, @$_ ) for @$xforms; } return $args }

That's not working code (swapBits() is undefined) but it gives feel for the notion. The problem then would be building the lookup tables, would become quite large depending upon the maximum dimensions you are hoping to handle. But if speed is the issue, and your current sub works, then using it to build the lookup once and storing it would allow runtime to be a bit quicker I think.

ADDENDUM: Having typed that in, I realise that there is no need to store the pairs of indexes. You may as well store the xformed values instead. It saves one level of depth in the lookup at the expense of the lower level having 2**n-bits values. Which is probably much of a muchness space-wise, but it avoids the need for swapBits().

You just lookup the correct array of xforms, then lookup each args value in that and replace it with the contents indexed. That would be much quicker. At the cost of the memory.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

In reply to Re: better algorithm: bitwise reordering by BrowserUk
in thread better algorithm: bitwise reordering by hv

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.