Skip to content

Instantly share code, notes, and snippets.

@tie
Last active December 20, 2019 06:53
Show Gist options
  • Save tie/1ad2c007c8d5f00f50af83d0f748ef3f to your computer and use it in GitHub Desktop.
Save tie/1ad2c007c8d5f00f50af83d0f748ef3f to your computer and use it in GitHub Desktop.
All binary strings of length n containing exactly k ones.
/*
// Poor man’s C++ solution.
#include<algorithm>
#include<string>
#include<iostream>
int main() {
int n, k;
std::cin >> n >> k;
std::string s(n, '1');
std::fill_n(s.begin(), n - k, '0');
do {
std::cout << s << std::endl;
} while (std::next_permutation(s.begin(), s.end()));
}
*/
// https://graphics.stanford.edu/~seander/bithacks.html
//
// But imagine we had 128 bit integers…
// Oh, wait.
//
typedef unsigned __int128 u128;
#ifdef __cplusplus
extern "C" {
int scanf(const char* fmt, ...);
int putchar(int c);
int puts(const char* s);
}
#else
int scanf(const char* restrict fmt, ...);
int putchar(int c);
int puts(const char* s);
#endif
u128 reverse(u128 v) {
u128 s = 128;
u128 mask = ~0;
while((s >>= 1) > 0) {
mask ^= (mask << s);
v = ((v >> s) & mask) | ((v << s) & ~mask);
}
return v;
}
void print(u128 v, int n) {
v <<= (128 - n);
v = reverse(v);
for(; n > 0; --n) {
if (v & 1)
putchar('1');
else
putchar('0');
v >>= 1;
}
puts("");
}
u128 next(u128 v) {
u128 t = (v | (v - 1)) + 1;
u128 w = t | ((((t & -t) / (v & -v)) >> 1) - 1);
return w;
}
int main() {
int n, k;
scanf("%d%d", &n, &k);
if(100 < n || n < k) {
puts("assertion failure");
return 1;
}
if(n <= 0) {
return 0;
}
if(k <= 0) {
print(0, n);
return 0;
}
u128 w = ~0;
w >>= (128 - k);
u128 o = 1;
o <<= n;
while(w < o) {
print(w, n);
w = next(w);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment