#! perl -slw use strict; use List::Util qw[ sum ]; sub nUniqRandsSumTo { my( $n, $target ) = @_; ## Prevent infinite loop. die 'No solution' if ( ( $n * ($n-1) ) / 2 ) > $target; my @rvs; { @rvs = $target; while( @rvs < $n ) { ## pick an element at my $i = int rand @rvs; ## Can't split 0, 1, 2 into two unique values redo if ( my $toSplit = $rvs[ $i ] ) < 3; my $first = int( rand $toSplit ); my $second = $toSplit - $first; ## try again if it split into two equal values redo if $first == $second; ## replace the original with the random pair splice @rvs, $i, 1, $first, $second; } my %seen; ## Do it all from scratch if we got dups ## Can be expensive if the target is close to the limit redo if grep{ ++$seen{ $_ } > 1 } @rvs; } return @rvs; } for( 1 .. 10 ) { my $target = 840 + int( rand 61 ); my @rands = sort{ $a <=> $b } nUniqRandsSumTo( 6, $target ); printf "sum: %3d [ %s ]\n", sum( @rands ), "@rands"; } __END__ c:\test>834245.pl sum: 896 [ 0 27 34 162 197 476 ] sum: 889 [ 35 77 109 179 196 293 ] sum: 878 [ 18 23 77 91 280 389 ] sum: 885 [ 6 37 68 136 154 484 ] sum: 854 [ 7 8 12 70 237 520 ] sum: 899 [ 8 10 29 101 293 458 ] sum: 858 [ 0 28 37 52 367 374 ] sum: 887 [ 1 8 11 22 43 802 ] sum: 899 [ 11 64 65 117 271 371 ] sum: 872 [ 7 14 40 43 154 614 ]