[Buffalo-pm] Re: [tpm] Bit Counting
Mike Stok
mike at stok.co.uk
Wed Oct 1 14:41:03 CDT 2003
On 1 Oct 2003, Derek Wueppelmann wrote:
> On Wed, 2003-10-01 at 14:40, Mike Stok wrote:
> > On Wed, 1 Oct 2003, Quantum Mechanic wrote:
> >
> > > I'm looking for an elegant way to generate a list of
> > > numbers whose binary representation has a given number
> > > of 1's. I also want to generate this list in numerical
> > > order.
> > >
> > > For example, with 4 bits on, less than 50:
> > >
> > > 15 1111
> > > 23 10111
> > > 27 11011
> > > 29 11101
> > > 30 11110
> > > 39 100111
> > > 43 101011
> > > 45 101101
> > > 46 101110
> > >
> > > Now it's easy enough to check every number up to the
> > > limit, but it seems there should be a more efficient
> > > method. On the other hand, the overhead involved in
> > > "skipping" some numbers may be more expensive than the
> > > straightforward approach.
> > >
> > > Anyone have any insights into this?
>
> Sorry I didn't post directly to your post but here's a thought.
? :-)
If you want perl then this does the same as he ruby but is smarter about
generating all 0s or 1s:
[mike at ratdog tmp]$ cat try.pl
#!/usr/bin/env perl
use POSIX 'ceil';
sub make_strings (&$$);
sub make_strings (&$$) {
my ( $block, $ones, $length ) = @_;
return if $ones > $length or $length < 1;
if ( $ones == 0 ) {
$block->( '0' x $length );
}
elsif ( $ones == $length ) {
$block->( '1' x $length );
}
else {
make_strings { $block->( "0$_[0]" ) } $ones, $length - 1;
make_strings { $block->( "1$_[0]" ) } $ones - 1, $length - 1
if $ones > 0;
}
}
( $ones, $limit ) = @ARGV;
$bits = ceil( log( $limit + 1 ) / log(2) );
ITERATION: {
make_strings {
my $s = shift;
my $value = oct("0b$s");
last ITERATION if $value > $limit;
print "$s $value\n";
} $ones, $bits;
}
[mike at ratdog tmp]$ ./try.pl 4 50
001111 15
010111 23
011011 27
011101 29
011110 30
100111 39
101011 43
101101 45
101110 46
(shame I can't put the & in the prototype at the end and be able to keep
dropping the sub keyword...)
Mike
--
mike at stok.co.uk | The "`Stok' disclaimers" apply.
http://www.stok.co.uk/~mike/ | GPG PGP Key 1024D/059913DA
mike at exegenix.com | Fingerprint 0570 71CD 6790 7C28 3D60
http://www.exegenix.com/ | 75D2 9EC4 C1C0 0599 13DA
More information about the Buffalo-pm
mailing list