http://www.perlmonks.org?node_id=467637


in reply to swap columns in a 2-dim array

Update: This matches the OPs algorithm:

#! perl -slw use strict; use List::Util qw[ shuffle ]; my @cols = shuffle qw/0 1 2 3 4 5 6 7 8 9 10 11/; my @nums = map { [qw/01 02 03 04 05 06 07 08 09 10 11 12/], } 1 .. 12; my @swapped = map{ [ @{ $_ }[ @cols[ 6 .. 11 ] ], @{ $_ }[ @cols[ 0 .. 5 ] ] ] } @nums; print "@$_" for @swapped; __END__ P:\test>467617 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09

Update2: And that can be improved (made clearer (IMO)):

#! perl -slw use strict; use List::Util qw[ shuffle ]; my @cols = shuffle 0 .. 11; my @nums = map { [ '01' .. '12' ] } 1 .. 12; my @swapped = map{ [ @{ $_ }[ @cols[ 6 .. 11 ] ], @{ $_ }[ @cols[ 0 .. 5 ] ] ] } @nums; print "@$_" for @swapped; __END__ P:\test>467617 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09 07 04 08 05 03 02 12 10 01 11 06 09

Don't!

A question mark regarding your spec is the bit about "2) each column must be swapped at least once.". That could be interpreted as "No column shall remain in it's original position"? Neither your nor my solution would meet that criteria.

This is easier on the eyes and should be a little more efficient than all those c-style loops.

#! perl -slw use strict; use List::Util qw[ shuffle ]; my @cols = shuffle qw/0 1 2 3 4 5 6 7 8 9 10 11/; my @nums = map { [qw/01 02 03 04 05 06 07 08 09 10 11 12/], } 1 .. 12; my @swapped = map{ [ @{ $_ }[ @cols ] ] } @nums; print "@$_" for @swapped; __END__ P:\test>467617 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09 12 05 06 04 02 08 10 11 03 01 07 09

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

Replies are listed 'Best First'.
Re^2: swap columns in a 2-dim array
by polettix (Vicar) on Jun 17, 2005 at 10:43 UTC
    Neither your nor my solution would meet that criteria.
    OP's solution meets the criterium you're de-obfuscating (only for an even number of columns, BTW, but the example assumes this). OP performs pair swapping, assuring that each column is swapped exactly once with a peer column. I think this is also the reason why OP is speaking C-ish: s?he needs to keep control over the indexes in @cols.

    Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

    Don't fool yourself.

      I meant my alternative reading of the criteria. That of "No column will end up in the same place". Unless I am reading his code wrong, it is possible that a given column could be swapped twice and end up in it's original position.

      Indeed, if his Fischer-Yates shuffle is correct, this has to be a possibility in order to meet the fairness criteria. All possible outcomes, including a resultant where the output is in the same ordering as the input have to have equal chance.

      I realise that by his original reading, swapping the order of a column twice, so that it ends up back in its original position, meets that criteria. However, the phraseology of the criteria is such, and the nature of the F_Y shuffle such, that explicitely noting it as a criteria made me consider the possibility that my alternative reading might be the true intent.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.
        Unless I am reading his code wrong, it is possible that a given column could be swapped twice and end up in it's original position.
        OP uses a shuffled array of 12 different indexes, from which s?he takes six pairs. Each pair contains two different indexes; each index falls into one, and only one, pair; in few words, s?he builds a partitions of the original set into six pairs. Then, s?he performs a single swap using the indexes each pair, which means that each location is read and written exactly once.
        I realise that by his original reading, swapping the order of a column twice, so that it ends up back in its original position, meets that criteria.
        The OP is also claiming that this is not a homework, so I think that your interpretation is the only possible - that is, an interpretation which looks at the final result and not at useless, noisy intermediate steps.

        Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

        Don't fool yourself.