patternMinor
Break an array into n equal or almost-equal sized sublists
Viewed 0 times
sublistsarrayintoequalalmostsizedbreak
Problem
I want to break a larger list into
Is there a more concise and more clear way to do this in Perl 6?
$num-lists smaller lists. I thought that there might be an option for rotor that would already do it, but I haven't found one.#!/bin/env perl6
my @a = 1 .. 13;
my @lists = fair-lists(@a, 3);
say @$_ for @lists;
sub fair-lists ( @array, $num-lists )
{
my $num-elements = @array.elems;
my $num-large = $num-elements % $num-lists; # remainder
my $num-small = $num-lists - $num-large;
my $small-size = floor($num-elements/$num-lists);
my $large-size = $small-size + 1; # same as ceiling($num-element/$num-lists);
my $first-large = ($num-small * $small-size);
my $last-small = $first-large - 1;
my @first-sublist = @array[ 0 .. $last-small];
my @second-sublist = @array[ $first-large .. $num-elements - 1 ];
my @small-lists = @first-sublist.rotor($small-size);
my @large-lists = @second-sublist.rotor($large-size);
my @all-lists = (@small-lists, @large-lists).flat;
return @all-lists;
}Is there a more concise and more clear way to do this in Perl 6?
Solution
Using
test it
roundrobin on a rotored array workssub fair-lists ( @array, Int $num-lists ) {
# "invert" the following "matrix"
roundrobin
# make it at least $num-lists long
|@array[{ 0 ..^ ( $_ max $num-lists ) }]\
# split it into chunks that are as big as the number of $num-lists
.rotor: $num-lists, :partial
}
say fair-lists( 1..1, 3 ).perl;
# ((1,), (Any,), (Any,)).Seq
say fair-lists( 1..4, 3 ).perl;
# ((1, 4), (2,), (3,)).Seq
test it
Context
StackExchange Code Review Q#119098, answer score: 5
Revisions (0)
No revisions yet.