davidj has asked for the wisdom of the Perl Monks concerning the following question:
The following question may sound like homework, but I assure you, it is not.
I have a situation where I need to swap columnar data in a 2-dimensional array. There are 3 conditions to the swap:
1) entire columns must be swapped (not just particular elements).
2) each column must be swapped at least once.
3) a column cannot be swapped with itself.
Here is the algorithm I am using:
1) fisher-yates an array of size equal to the number of columns.
2) in an outer loop, interate over each row in the array.
3) in an inner loop, use the two halves of the fisher-yated ( is that even a word? ) to determine the elements to swap. That is, if the fisher-yated array looks like [3,5,4,6,2,1], then effectively, col 3 and col 6 are swapped, col 5 and col 2 are swapped, and col 4 and col 1 are swapped.
What I do not like about what I have is the element-by-element swapping in the inner loop. I am concerned about the efficiency of the algorithm and whether there is a more efficient way to accomplish what I need.
code using a simple 12x12 matrix as an example:
output:#!/usr/bin/perl my @cols = qw/0 1 2 3 4 5 6 7 8 9 10 11/; fys( \@cols ); my @nums = ( [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], [qw/01 02 03 04 05 06 07 08 09 10 11 12/], ); for( my $i = 0; $i < 12; $i++) { for( my $j = 0; $j < 6; $j++) { ($nums[$i][ $cols[$j] ], $nums[$i][ $cols[$j+6] ]) = ($nums[$i +][ $cols[$j+6] ], $nums[$i][ $cols[$j] ]); } } &printit; sub printit() { for( my $i = 0; $i < 12; $i++) { print "@{ $nums[$i] } "; print "\n"; } } sub fys { my $arr = shift; my $i; for( $i = @{ $arr }; $i--;) { my $j = int rand ($i + 1); next if $i == $j; @$arr[$i,$j] = @$arr[$j,$i]; } }
As always, thank you for your input,03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10 03 04 01 02 11 08 09 06 07 12 05 10
davidj
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: swap columns in a 2-dim array
by tlm (Prior) on Jun 17, 2005 at 08:59 UTC | |
Re: swap columns in a 2-dim array
by bart (Canon) on Jun 17, 2005 at 09:45 UTC | |
Re: swap columns in a 2-dim array
by tlm (Prior) on Jun 17, 2005 at 10:47 UTC | |
Re: swap columns in a 2-dim array
by BrowserUk (Patriarch) on Jun 17, 2005 at 10:16 UTC | |
by polettix (Vicar) on Jun 17, 2005 at 10:43 UTC | |
by BrowserUk (Patriarch) on Jun 17, 2005 at 10:55 UTC | |
by polettix (Vicar) on Jun 17, 2005 at 12:26 UTC | |
by BrowserUk (Patriarch) on Jun 17, 2005 at 13:08 UTC | |
Re: swap columns in a 2-dim array
by polettix (Vicar) on Jun 17, 2005 at 10:36 UTC | |
Re: swap columns in a 2-dim array
by Forsaken (Friar) on Jun 17, 2005 at 12:03 UTC | |
Re: swap columns in a 2-dim array
by TedPride (Priest) on Jun 17, 2005 at 16:21 UTC |