use strict; use warnings; use constant { SEP => $;, TRY => 5, # arbitrary }; use Data::Dump; use List::Util "shuffle"; my @AoAs = ( [ [ 2, 3, 4, 5 ], [ 2, 3, 4, 5 ], [ 2, 3, 4, 5 ], ], [ [ 3, 2, 4, 5 ], [ 4, 3, 2, 5 ], [ 2, 5, 4, 3 ], ], ); for (@AoAs) { dd $_; randomise($_); } sub randomise { my ($AoA) = @_; my %seen; @seen{map mk_key(@$_), @$AoA} = (1) x @$AoA; for my $i (0 .. $#$AoA) { my $tries = 0; while (1) { my @shuffled = shuffle @{$AoA->[$i]}; if ($seen{mk_key(@shuffled)}++) { die "Too many tries" if ++$tries >= TRY; } else { $AoA->[$i] = [@shuffled]; last; } } } dd $AoA; } sub mk_key { join SEP, @_; } #### [[2 .. 5], [2 .. 5], [2 .. 5]] [[2, 4, 3, 5], [2, 3, 5, 4], [2, 5, 3, 4]] [[3, 2, 4, 5], [4, 3, 2, 5], [2, 5, 4, 3]] [[5, 4, 3, 2], [4, 5, 2, 3], [5, 2, 3, 4]] #### [[2 .. 5], [2 .. 5], [2 .. 5]] [[4, 5, 2, 3], [3, 5, 2, 4], [2, 5, 4, 3]] [[3, 2, 4, 5], [4, 3, 2, 5], [2, 5, 4, 3]] [[5, 4, 3, 2], [3, 4, 5, 2], [2, 5, 3, 4]]