BramVanOosterhout has asked for the wisdom of the Perl Monks concerning the following question:

There is a mistake in the fisher_yates_shuffle code above. The shuffle loop will never include the last element of the array.

--$i is calculated before entering the body. And rand($i + 1) will never return the value of $i.

The loop control that works is:

for ( my $i = @$array; $i; $i-- ) {

This was originally posted as an Answer to the Categorized Question How do I shuffle an array?. It was removed from the CatQA section because it is not a good answer.

Replies are listed 'Best First'.
Re: How do I shuffle an array?
by AnomalousMonk (Archbishop) on Jul 10, 2017 at 07:08 UTC
    The shuffle loop will never include the last element of the array. ... rand($i + 1) will never return the value of $i.

    BramVanOosterhout: Have you checked these assertions of How do I shuffle an array??

    The undefs running through the outputs of the for-loop implementation suggest a serious problem. The problem may stem from the notion that  scalar @array yields the index of the highest element in the array; in fact, it yields the number of elements in the array, and  $#array yields the highest index. (This assumes the default value of 0 for the Perl special, now deprecated, variable  $[ (see perlvar). I haven't checked, but maybe you can get correct behavior from the for-loop version if you change  $[ to 1 — but don't do that!)

    Update: I've since checked, and it does seem as if the given for-loop implementation works correctly with  $[ == 1 — but again, don't do that!


    Give a man a fish:  <%-{-{-{-<