Hi BrowserUk,
I agree that there really isn't a clean way to do this. I'm not really sure what your primary motivation is though, whether it's efficiency or readability.
One way to reform the problem though is to say that you don't want the range [0,M] inclusive, but actually [0,M+1) without including the end point. This way you can avoid having to treat the last or first segment as special case.
Here is how I would redo your code by creating an intermediate data structure to contain the points
#! perl -slw use strict; our $N //= 2; our $M //= 1e6; $M++; # No segment contains the upper end point. my @points = map {int $M * $_ / $N} (0..$N); my @ranges = map {[$points[$_], $points[$_+1]-1]} (0..$#points-1); printf "%2d : from %7d to %7d (%7d)\n", $_, @{ $ranges[ $_ ] }, $ranges[ $_ ][ 1 ] - $ranges[ $_ ][ 0 ] + 1 for 0 .. $#ranges; __END__
- Miller
In reply to Re: Split range 0 to M into N non-overlapping (roughly equal) ranges.
by wind
in thread Split range 0 to M into N non-overlapping (roughly equal) ranges.
by BrowserUk
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |