I might have accidentally broken my previous post, so I just post the final results here. Not because my solutions are faster (tux_a_fp is sloooooow), but as they show TIMTOWTDI
use Algorithm::FastPermute;
sub tux_a_fp {
my ($length, $ones) = @_;
my @l = ((0) x ($length - $ones), (1) x $ones);
my %seen;
permute { $seen{join "" => @l}++ } @l;
[ keys %seen ];
}
sub tux_for {
my ($length, $ones) = @_;
my $s1 = "1" x $ones;
my $s0 = "0" x ($length - $ones);
[ map { substr unpack ("b*", $_), 0, $length }
grep { $ones == unpack "%32b*" => $_ }
map { pack "L<", $_ }
oct "0b$s1" .. oct "0b$s1$s0"
];
}
sub tux_tr {
my ($length, $ones) = @_;
my $s1 = "1" x $ones;
my $s0 = "0" x ($length - $ones);
[ grep { $ones == tr/1/1/ }
map { substr unpack ("b*", pack "L<",$_), 0, $length }
oct "0b$s1" .. oct "0b$s1$s0"
];
}
update: another variation on recursion:
sub tux_recur {
my ($length, $ones) = @_;
$length or return [];
$ones or return [ "0" x $length ];
$ones == $length and return [ "1" x $length ];
[ ( map { "0$_" } @{tux_recur ($length - 1, $ones )} ),
( map { "1$_" } @{tux_recur ($length - 1, $ones - 1)} ),
];
}
On my box ends between Eily and tybalt89. GrandFather is still the fastest:
Discipulus 0.103/s
tux_a_fp 1.43/s
choroba 1496/s
tybalt89_re 1558/s
tux_tr 1777/s
tux_for 2807/s
johngg 2828/s
Eily 2851/s
tux_recur 2889/s
tybalt89 3654/s
salva 4187/s
Eily_LanX 5110/s
GrandFather 6119/s
Enjoy, Have FUN! H.Merijn