Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

(CLPM) reorder via swap

by japhy (Canon)
on Aug 17, 2004 at 16:16 UTC ( #383722=obfuscated: print w/replies, xml ) Need Help??

Geez. This isn't supposed to be obfuscation, but it ended up that way, in the sense that the algorithm is a bit difficult to extract. The swapping is the easy part... those two parallel arrays are not.
# reorder an array using only swap(ARRAY, X, Y), # given a new set of indices my @array = qw( put these in a different order ); my @order = qw( 1 3 5 4 2 0 ); reorder_swap(\@array, \@order); # expected outcome: # qw( these a order different in put ) sub reorder_swap { my ($a, $o) = @_; my @P = my @R = 0 .. $#$o; for (0 .. $#$o) { next if $P[$$o[$_]] == $_; swap($a, $P[$$o[$_]], $_); (@P[$R[$_],$$o[$_]], @R[$P[$$o[$_]],$_]) = (@P[$$o[$_],$R[$_]], @R[$_,$P[$$o[$_]]]); } } sub swap { my ($a, $x, $y) = @_; @$a[$x,$y] = @$a[$y,$x]; }
For simplicity's sake, here's the for loop with a temporary variable instead:
for (0 .. $#$o) { my $idx = $$o[$_]; next if $P[$idx] == $_; swap($a, $P[$idx], $_); (@P[$R[$_],$idx], @R[$P[$idx],$_]) = (@P[$idx,$R[$_]], @R[$_,$P[$idx]]); }
_____________________________________________________
Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

Replies are listed 'Best First'.
Re: (CLPM) reorder via swap
by o0lit3 (Friar) on Aug 17, 2004 at 18:53 UTC

    Without using swap, we have a slightly less obfuscated and (uninteresting) way...

    @array = qw(put these in a different order); @order = qw(1 3 5 4 2 0); print reorder(\@array, \@order); sub reorder() { #23456789012345678901234 map${@_[0]}[$_],@{$_[1]} }

    Uninteresting as it may be, it might make for a decent golf... Can this be done in fewer strokes?

    What if the input were two strings on <STDIN>, separated by a line feed? We then might have something like:

    #!/perl -ln0a map$F[$_],@F[@F/2..$#F]
      Assuming we want to return a list in the ordered fashion:
      sub reorder { #234567890123456 @{+pop}[@{+pop}] }
      I'm taking an array slice instead of using map(). And we can get even shorter if we call it as reorder(@elements, \@neworder):
      sub reorder { #2345678901 @_[@{+pop}] }
      _____________________________________________________
      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart

        Beautiful and elegant... it's simplicity like this that always reminds me why I love this language.

        But please help me out a little. What is the + operator doing here? I know that @{+pop} is somehow saying the same as @{pop()}, but I'm not sure why. ...And while I'm on the subject, why am I not allowed to simply say @{pop} (besides the fact that I've used a split infinitve)?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: obfuscated [id://383722]
Approved by Grygonos
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2023-10-04 17:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?