#include #include #define CHECK_BIT(var,pos) (((var) & (pos)) ? 1LL : 0LL) #define n 9 #if n%2==0 #define NODD 0 #else #define NODD 1 #endif mpz_t bigsum; mpz_t tmp; unsigned int k; long long int prod[n]; inline void updatesum(unsigned int odd) { mpz_set_si(tmp,1); for(k=0; k < n; k++) { if(prod[k] == 0LL) { return; } mpz_mul_si(tmp,tmp,prod[k]); } if(NODD) mpz_mul_si(tmp,tmp, -1); if(odd) mpz_sub(bigsum,bigsum,tmp); else mpz_add(bigsum,bigsum,tmp); } int main() { unsigned long long int i,swp,min; unsigned long long int gray = 0; unsigned long long int bigN = (1LL<<(3*n)); mpz_init(bigsum); mpz_init(tmp); for (k=0; k < n; k++) prod[k] = 0LL; for(i=0LL; i < bigN; i++) { min = i & (-i); // bit changed in graycode gray ^= min; // graycode if(min&gray) // +1 { swp=min>>1; for (k=0; k < n && swp>>(k+1); swp>>=1) { prod[k] += CHECK_BIT(gray,swp)*CHECK_BIT(gray,swp>>(k+1)); } swp=min<<1; for (k=0; k < n && swp<<(k+1) < bigN; k++, swp<<=1) { prod[k] += CHECK_BIT(gray,swp)*CHECK_BIT(gray,swp<<(k+1)); } } else // 0 { swp=min>>1; for (k=0; k < n && swp>>(k+1); swp>>=1) { prod[k] -= CHECK_BIT(gray,swp)*CHECK_BIT(gray,swp>>(k+1)); } swp=min<<1; for (k=0; k < n && swp<<(k+1) < bigN; k++, swp<<=1) { prod[k] -= CHECK_BIT(gray,swp)*CHECK_BIT(gray,swp<<(k+1)); } } updatesum(i&1); } gmp_printf("Triplet Skolem sequences of order %d: %Zd\n", n, bigsum); }