Okay, sorry! Try this iterator then. It will handle upto 32 0s + 1s.
If you uncomment the second example it runs on a bit.
Update: Had to tweak the termination condition. It works now but I'm not happy with it.
Update2: D'oh! No need to count both 1s and 0s.
#! perl -slw
use strict;
sub combs {
my( $ones, $zeros ) = @_;
my $n = $ones+$zeros;
my $max = 2**$n;
my $p = 0;
return sub {
my $x = '';
$x = unpack "b$n", pack 'V', $p++
until $x =~ tr[1][] == $ones
or $p > $max and return;
return $x;
}
}
my $iter = combs( 2, 3 );
print while $_ = $iter->();
#my $iter = combs( 14, 6 );
#print while $_ = $iter->();
__END__
C:\test>junk7
11000
10100
01100
10010
01010
00110
10001
01001
00101
00011
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
That's a very nice algorythm, but it's a bit slow, and 2 questions:
1. how can i work with (much)more that 32 1's+0's ?
2. why do i need $max to be 2**$n ? when combs(2,3) gives 10 reasults not 32 ???
i need this sub{} to play with the strings that contain that number of 1's and 0's, not the numbers that contain them.
| [reply] |
1. how can i work with (much) more that 32 1's+0's ?
You almost certainly do not need to. It could be extended to handle 53-bits quite easily, but given that it would take the fastest algorithm in this thread ~462 years to deal with the numbers possible from that small number of bits. And as your target of 435 + 343 will take, for all intents and purposes, that number * infinity--so many times longer than the universe has existed as to be totally meaningless--you simply don't.
One has to wonder what use, other than as another outing for Algorithm::Loops, that you thought you were going to put this to?
Had you been dealing with reasonable numbers, I've got a specialisation of tye's nextPermute() that handles this particular problem about 3 1/2 times more quickly, but unless your name is Q, it probably won't help :)
Update: Seems someone didn't bellieve me:
sub combs2 {
my( $z, $o ) = @_;
my $str = '0'x$z . '1'x$o;
my $l = length $str;
return sub {
my $p = 1+rindex( $str, '01' ) or return;
my $r = 1+rindex( $str, '1');
my $s = 1+rindex( $str, '0', $r-1);
substr( $str, $s, 0 ) = substr( $str, $r, $l-$r, '' );
my $q = index( $str, '1', $p );
substr( $str, $p-1, 1 ) = '1';
substr( $str, $q, 1 ) = '0';
$str;
};
}
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |