Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

(CLPM) reorder via swap

by japhy (Canon)
on Aug 17, 2004 at 16:16 UTC ( [id://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?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-04-25 10:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found