#include <iostream>
using namespace std;

unsigned long long snoob(unsigned long long x)
{
    unsigned long long smallest = x & -x;
    unsigned long long ripple   = x + smallest;
    unsigned long long ones     = x ^ ripple;
    ones = (ones >> 2)/smallest;
    return ripple|ones;
}

template<typename T, size_t N>
void combines( T(&a)[N], size_t K)
{
    static_assert( N < 64 );
    if (K == 0 || K > N ) return;
    unsigned long long x = (1ull << K) - 1;
    for(;x < (1ull << N); x = snoob(x))
    {
        unsigned long long y = x;
        for(size_t i = 0; y; y >>= 1, i++)
            if (y&1) cout << a[i] << " ";
        cout << endl;
    }
}

int main(int argc, char * argv[])
{
    int a[] = {1,3,5,8,0,7};
    combines(a,3);
}
