sub nextpart { ## collect all the trailing 1s my $x = 0; $x += pop while @_ and $_[-1] == 1; return if ! @_; ## collect 1 from the rightmost remaining guy $_[-1]--; $x++; ## re-distribute the collected amount in increments of $_[-1] while ($x > $_[-1]) { push @_, $_[-1]; $x -= $_[-1]; } push @_, $x; @_; } ## example usage: my @part = (5); do { print "@part\n"; } while (@part = nextpart @part); __OUTPUT__ 5 4 1 3 2 3 1 1 2 2 1 2 1 1 1 1 1 1 1 1