#! perl -slw use strict; use List::Util qw[ sum ]; our $SHIPS ||= 10; our $REPS ||= 1e5; sub pick { my( $weights, $total ) = @_; my $rand = rand $total; ( $rand -= $weights->[ $_ ] ) < 0 and return $_ for 0 .. $#$weights; } sub pickAll{ my @weights = @_; my $total = sum @weights; my @order; for( 0 .. $#_ ) { my $pick = pick( \@weights, $total ); push @order, $pick; $total -= $weights[ $pick ]; $weights[ $pick ] = 0; } return @order; } my @weights = map rand( 16 ), 1 .. $SHIPS; print "$_ : $weights[ $_ ]" for 0 .. $#weights; my $total = sum @weights; print "\n"; print join ' ', pickAll( @weights ) for 1 .. $REPS;