in reply to Odometer pattern iterator (in C). (Updated.)
$_ = '00111';
1 while print("$_\n"), s/.*\K01(.*)/10 . reverse $1/e;
Wow! This is impressively simple. I would have never thought that this was possible.
As cute as that is (and it is damn cute!), calling back into Perl and then invoking the regex engine won't make for a performant solution.
Also, as I've highlighted in my update above, I want the positions of the set bits, not the bit patterns themselves.
Translating that regex into C is trivial: (1) Find rightmost occurence of substring '01' (we are done if there is none), (2) change '01' to '10', (3) reverse the string to the right of that.
Finding the indices of the '1's is also simple.
Simple yes, but not quick.
A chance to brush off my C :)
// inc_c - http://perlmonks.org/?node_id=1128230
#define M 5 // place
#define N 3 // number of elements wanted
static int place[N];
for(int i = 0; i < N; i++)
if(i < N - 1 ? place[i] < place[i + 1] - 1 : place[i] < M - 1 )
for(int j = i - 1; j >= 0; j--) place[j] -= place;
main(int argc, char **argv)
int more = 1;
for(i = 0; i < N; i++) place[i] = i;
for(i = 0; i < N; i++) printf(" %d", place[i]);
more = step();
That works. But it's about 40% slower than the A::C version I nicked. 11 seconds instead of 8 for the 601 million 16 from 32:
[17:27:38.79] C:\test\humanGenome>junk 32 16
[17:41:10.28] C:\test\humanGenome>junk 32 16
[17:41:17.49] C:\test\humanGenome>junk2 32 16
[17:41:40.82] C:\test\humanGenome>junk2 32 16
junk2 is your code adapted to count rather than print.
Results (111 votes). Check out past polls.