use strict; my %npart; sub cntpart1 { my($n, $m) = @_; $n = 0+$n; $m = 0+$m; my $c = \$npart{$n." ".$m}; defined($$c) and return $$c; $n <= 0 and return $$c = 1; my $s = 0; for my $k (1 .. ($m < $n ? $m : $n)) { $s += cntpart1($n - $k, $k); } $$c = $s; } sub randpart1 { my($n, $m) = @_; $n <= 0 and return; my($s, $k) = 0; for my $j (1 .. ($m < $n ? $m : $n)) { my $p = cntpart1($n - $j, $j); rand($s += $p) < $p and $k = $j; } $k, randpart1($n - $k, $k); } sub randpart { my($n) = @_; randpart1($n, $n); }