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 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)?

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?